diff --git a/.gitattributes b/.gitattributes index 8e948c5..3facc7c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,88 @@ * text=auto !eol +/Makefile.in -text +/aclocal.m4 -text +adns/Makefile -text +adns/adns.h -text +adns/check.c -text +adns/config.h -text +adns/config.h.in -text +adns/dlist.h -text +adns/event.c -text +adns/general.c -text +adns/internal.h -text +adns/parse.c -text +adns/query.c -text +adns/reply.c -text +adns/setup.c -text +adns/transmit.c -text +adns/tvarith.h -text +adns/types.c -text +/client.c -text +/client.h -text +/conf.c -text +/conf.h -text +/config.guess -text +/config.h.in -text +/config.sub -text +/configure -text +/configure.in -text +/defines.h -text +/dict.c -text +/dict.h -text +/dotconf.c -text +/dotconf.h -text +/hash.c -text +/hash.h -text +/install-sh -text +libevent/Makefile.am -text +libevent/Makefile.in -text +libevent/acconfig.h -text +libevent/aclocal.m4 -text +libevent/buffer.c -text +libevent/compat/err.h -text +libevent/compat/sys/_time.h -text +libevent/compat/sys/queue.h -text +libevent/compat/sys/tree.h -text +libevent/config.h.in -text +libevent/configure -text +libevent/configure.in -text +libevent/epoll.c -text +libevent/epoll_sub.c -text +libevent/err.c -text +libevent/evbuffer.c -text +libevent/event.3 -text +libevent/event.c -text +libevent/event.h -text +libevent/evsignal.h -text +libevent/install-sh -text +libevent/kqueue.c -text +libevent/missing -text +libevent/mkinstalldirs -text +libevent/poll.c -text +libevent/rtsig.c -text +libevent/sample/Makefile.am -text +libevent/sample/Makefile.in -text +libevent/sample/event-test.c -text +libevent/sample/signal-test.c -text +libevent/sample/time-test.c -text +libevent/select.c -text +libevent/signal.c -text +libevent/stamp-h.in -text +libevent/test/Makefile.am -text +libevent/test/Makefile.in -text +libevent/test/bench.c -text +libevent/test/regress.c -text +libevent/test/test-eof.c -text +libevent/test/test-init.c -text +libevent/test/test-time.c -text +libevent/test/test-weof.c -text +libevent/test/test.sh -text +/list.c -text +/list.h -text +/log.c -text +/log.h -text +/main.c -text +/mqserver.cfg -text +/sock.c -text +/sock.h -text +/version.h -text diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..2c0b761 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,147 @@ +# Makefile for NeoStats +CC=@CC@ +CFLAGS =@CFLAGS@ +LD=ld +RM=/bin/rm -rf +LDFLAGS = @LDFLAGS@ @LIBS@ +MODLDFLAGS = @MODLDFLAGS@ +INSTALL = @INSTALL@ +INSTALL_MOD = @INSTALL_DATA@ +NEOINCLUDES = -I. -Iadns -Ilibevent +MODINCLUDES = -I. -I../.. -I../../adns +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +MODULES = @MODULES@ +DIRECTORY = @prefix@ +MODDIRECTORY = @prefix@/dl +DATADIRECTORY = @prefix@/data +INCDIRECTORY = @prefix@/include +DISTDIR = @PACKAGE@-@VERSION@ +extauth_src = @EXTAUTH_SRC@ +extauth_objs = @EXTAUTH_OBJS@ +LEX = @LEX@ +LEXLIBS = @LEXLIBS@ +YACC = @YACC@ + + +NEOCFLAGS = $(CFLAGS) +EXTRA_LDFLAGS = -Llibevent -levent + +PROGS = mqserver +CONF = +DOCS = +DOCS_PROGS = +DATA = + +OBJS = ${SRCS:.c=.o} +SRCS = main.c hash.c list.c log.c dotconf.c sock.c conf.c client.c dict.c + +INCLUDES = config.h hash.h list.h mqserver.h log.h dotconf.h dict.h + +BUILDFILES = configure config.sub config.guess *.in + +DISTFILES = $(INCLUDES) $(COREINCS) $(SRCS) $(IRCDSRC) $(IRCDINC) \ + $(BUILDFILES) $(DATA) $(DOCS) $(DOCS_PROGS) $(CONF) + +ADNSFILES = adns/check.o adns/event.o adns/general.o adns/parse.o \ + adns/query.o adns/reply.o adns/setup.o adns/transmit.o adns/types.o +SUBDIRS = +DISTLIBS = +DISTMOD = + +all: mqserver + +modules: + (cd adns; $(MAKE) $@) + (cd libevent; $(MAKE) libevent.a) + +buildversion: + @(if test -f version.sh ; then $(SHELL) version.sh; else echo > version.h; fi) + +mqserver: buildversion modules $(OBJS) + $(CC) $(LDFLAGS) $(OBJS) $(EXTRA_LDFLAGS) $(ADNSFILES) -o $@ + +# include dependency info +@MAKEDEPENDENCIES@ + +.c.o: + $(CC) $(NEOCFLAGS) $(NEOINCLUDES) -c $< + $(CC) -MM $(NEOINCLUDES) -c $< > $*.d + +clean: + (cd dl; $(MAKE) $@) + $(RM) *.o neostats *.cache Makefile config.h *.log *.a *.d *.exe version.h + +distclean: + (cd dl; $(MAKE) $@) + $(RM) *.o neostats *.cache Makefile config.h *.log *.a *.d *.exe config.status version.h + +install: neostats + @echo "Installing ..." + @$(RM) @prefix@/include/*.h + $(INSTALL) -m 755 -d @prefix@ + $(INSTALL) -m 755 -d @prefix@/dl + $(INSTALL) -m 755 -d @prefix@/include + $(INSTALL) -m 755 -d @prefix@/doc + $(INSTALL) -m 755 -d @prefix@/data + $(INSTALL) -m 750 -d @prefix@/logs + $(INSTALL) -m 755 $(PROGS) @prefix@ + $(INSTALL_DATA) $(CONF) @prefix@ + $(INSTALL_DATA) $(DOCS) @prefix@/doc + $(INSTALL) -m 755 $(DOCS_PROGS) @prefix@/doc + $(INSTALL_DATA) $(DATA) @prefix@/data + $(INSTALL_DATA) $(INCLUDES) @prefix@/include + $(INSTALL_DATA) version.h @prefix@/include + $(INSTALL_DATA) @IRCD_FILES_INC@ @prefix@/include + (cd adns; $(MAKE) $@) + (cd sqlsrv; $(MAKE) $@) + (cd dl; $(MAKE) $@) + (cd tools; $(MAKE) $@) + @echo "Done." + @cat INSTNOTES + @if test -f INSTNOTES.svn ; then cat INSTNOTES.svn ; fi + +dist: + @echo -n "Creating Directories" + @$(RM) $(DISTDIR) + @echo -n "." + @mkdir $(DISTDIR) + @echo -n "." + @mkdir $(DISTDIR)/dl + @echo -n "." + @for subdir in $(SUBDIRS); do \ + echo -n "."; \ + mkdir $(DISTDIR)/$$subdir; \ + chmod 777 $(DISTDIR)/$$subdir; \ + done + @echo "Done" + @echo -n "Copying Core Distribution files" + @for file in $(DISTFILES); do \ + echo -n "."; \ + cp -pr $$file $(DISTDIR)/$$file; \ + done + @$(RM) $(DISTDIR)/config.h + @$(RM) $(DISTDIR)/configure.in + @echo "Done" + @echo "Copying Library Distribution files" + @for subdir in $(DISTLIBS); do \ + mkdir $(DISTDIR)/$$subdir; \ + chmod 777 $(DISTDIR)/$$subdir; \ + (cd $$subdir && $(MAKE) dist DISTDIR=../$(DISTDIR)/$$subdir && cd ..) || exit 1; \ + done + @echo "Done" + @echo "Copying Tools Distribution files" + @(cd tools && $(MAKE) dist DISTDIR=../$(DISTDIR)/tools && cd ..) || exit 1; + @echo "Done" + @echo "Copying Module Distribution files" + @for mod in $(DISTMOD); do \ + mkdir $(DISTDIR)/dl/$$mod; \ + (cd dl/$$mod && $(MAKE) dist DISTDIR=../../$(DISTDIR)/dl/$$mod && cd ../..) || exit 1; \ + done + @echo "Done" + @tar -czf $(DISTDIR).tar.gz $(DISTDIR)/* +# @$(RM) $(DISTDIR) + @echo "Tar file $(DISTDIR).tar.gz created. Freshmeat time!" + +# Catch any changes in compilation options at the top of this file +$(OBJS): Makefile diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..5dc072b --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,4243 @@ +# aclocal.m4 generated automatically by aclocal 1.6 -*- Autoconf -*- + +# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# 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. + +# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*- + +# Copyright 1996, 1997, 2000, 2001 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_PREREQ([2.13]) + +# serial 6 + +# 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. We must strip everything past the first ":", +# and everything past the last "/". + +# _AM_DIRNAME(PATH) +# ----------------- +# Like AS_DIRNAME, only do it during macro expansion +AC_DEFUN([_AM_DIRNAME], + [m4_if(regexp([$1], [^.*[^/]//*[^/][^/]*/*$]), -1, + m4_if(regexp([$1], [^//\([^/]\|$\)]), -1, + m4_if(regexp([$1], [^/.*]), -1, + [.], + patsubst([$1], [^\(/\).*], [\1])), + patsubst([$1], [^\(//\)\([^/].*\|$\)], [\1])), + patsubst([$1], [^\(.*[^/]\)//*[^/][^/]*/*$], [\1]))[]dnl +])# _AM_DIRNAME + + +# The stamp files are numbered to have different names. +# We could number them on a directory basis, but that's additional +# complications, let's have a unique counter. +m4_define([_AM_STAMP_Count], [0]) + + +# _AM_STAMP(HEADER) +# ----------------- +# The name of the stamp file for HEADER. +AC_DEFUN([_AM_STAMP], +[m4_define([_AM_STAMP_Count], m4_incr(_AM_STAMP_Count))dnl +AS_ESCAPE(_AM_DIRNAME(patsubst([$1], + [:.*])))/stamp-h[]_AM_STAMP_Count]) + + +# _AM_CONFIG_HEADER(HEADER[:SOURCES], COMMANDS, INIT-COMMANDS) +# ------------------------------------------------------------ +# We used to try to get a real timestamp in stamp-h. But the fear is that +# that will cause unnecessary cvs conflicts. +AC_DEFUN([_AM_CONFIG_HEADER], +[# Add the stamp file to the list of files AC keeps track of, +# along with our hook. +AC_CONFIG_HEADERS([$1], + [# update the timestamp +echo 'timestamp for $1' >"_AM_STAMP([$1])" +$2], + [$3]) +])# _AM_CONFIG_HEADER + + +# AM_CONFIG_HEADER(HEADER[:SOURCES]..., COMMANDS, INIT-COMMANDS) +# -------------------------------------------------------------- +AC_DEFUN([AM_CONFIG_HEADER], +[AC_FOREACH([_AM_File], [$1], [_AM_CONFIG_HEADER(_AM_File, [$2], [$3])]) +])# AM_CONFIG_HEADER + +# Do all the work for Automake. -*- Autoconf -*- + +# 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. + +# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 8 + +# 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... + + +AC_PREREQ([2.13]) + +# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow +# the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl + +# 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_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])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) +AM_MISSING_PROG(AMTAR, tar) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +# 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 + +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_][CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_][CC], + defn([AC_PROG_][CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_][CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_][CXX], + defn([AC_PROG_][CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + +# Copyright 2002 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# 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. +AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.6"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.6])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright 2001, 2002 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# _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], +[AC_FOREACH([_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])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright 1996, 1997, 2000, 2001 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# 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 ( + 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 + rm -f conftest.file + 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 + + 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)]) + +# -*- Autoconf -*- + + +# Copyright 1997, 1999, 2000, 2001 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# 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 supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_AUX_DIR_EXPAND + +# Copyright 2001 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# 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. + +# Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.13]) + +AC_DEFUN([AM_AUX_DIR_EXPAND], [ +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright 2001 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright 2001 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# 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="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# serial 4 -*- Autoconf -*- + +# Copyright 1999, 2000, 2001 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +# 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", "GCJ", or "OBJC". +# 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 + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'] + [$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'. + 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 + + 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 + for depmode in $am_compiler_list; do + # 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. + echo '#include "conftest.h"' > conftest.c + echo 'int i;' > conftest.h + echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf + + case $depmode in + 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 + ;; + none) break ;; + esac + # 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. + if depmode=$depmode \ + source=conftest.c object=conftest.o \ + depfile=conftest.Po tmpdepfile=conftest.TPo \ + $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 && + grep conftest.h conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + am_cv_$1_dependencies_compiler_type=$depmode + break + 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_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[rm -f .deps 2>/dev/null +mkdir .deps 2>/dev/null +if test -d .deps; then + DEPDIR=.deps +else + # MS-DOS does not allow filenames that begin with a dot. + DEPDIR=_deps +fi +rmdir .deps 2>/dev/null +AC_SUBST([DEPDIR]) +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking Speeds up one-time builds + --enable-dependency-tracking Do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright 1999, 2000, 2001, 2002 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +#serial 2 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + if (sed 1q $mf | fgrep 'generated by automake') > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. + DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + test -z "$DEPDIR" && continue + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n -e '/^U = / s///p' < "$mf"` + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # 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 -e ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/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"]) +]) + +# Copyright 2001 Free Software Foundation, Inc. -*- Autoconf -*- + +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +doit: + @echo done +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 +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST(am__include) +AC_SUBST(am__quote) +AC_MSG_RESULT($_am_result) +rm -f confinc confmf +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright 1997, 2000, 2001 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 5 + +AC_PREREQ(2.13) + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +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])]) + +# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- + +# serial 46 AC_PROG_LIBTOOL +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +]) + +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +_LT_AC_PROG_ECHO_BACKSLASH +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE(libtool-lock, + [ --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 +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + 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 + 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_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + 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 + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac + +_LT_AC_LTCONFIG_HACK + +]) + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN(_LT_AC_CHECK_DLFCN, +[AC_CHECK_HEADERS(dlfcn.h) +])# _LT_AC_CHECK_DLFCN + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl + +# 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]*\)'] + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Define system-specific variables. +case $host_os in +aix*) + [symcode='[BCDT]'] + ;; +cygwin* | mingw* | pw32*) + [symcode='[ABCDGISTW]'] + ;; +hpux*) # Its linker distinguishes data from code symbols + lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + ;; +irix*) + [symcode='[BCDEGRST]'] + ;; +solaris* | sysv5*) + [symcode='[BDT]'] + ;; +sysv4) + [symcode='[DFNSTU]'] + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + [symcode='[ABCDGISTW]'] +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. +[lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"] + + # Check to see that the pipe works correctly. + pipe_works=no + rm -f conftest* + cat > conftest.$ac_ext < $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 egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +[lt_preloaded_symbols[] =] +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if AC_TRY_EVAL(ac_link) && test -s conftest; then + pipe_works=yes + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AC_FD_CC + fi + else + echo "cannot find nm_test_var in $nlist" >&AC_FD_CC + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "$progname: failed program was:" >&AC_FD_CC + cat conftest.$ac_ext >&5 + fi + rm -f 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 +]) +global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" +if test -z "$lt_cv_sys_global_symbol_pipe"; then + global_symbol_to_cdecl= +else + global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" +fi +if test -z "$global_symbol_pipe$global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + +# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR +# --------------------------------- +AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR], +[# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac +fi +])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn;t interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +AC_DIVERT_POP +])# _LT_AC_PROG_ECHO_BACKSLASH + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN(_LT_AC_TRY_DLOPEN_SELF, +[if test "$cross_compiling" = yes; then : + [$4] +else + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#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 + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=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; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN(AC_LIBTOOL_DLOPEN_SELF, +[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 + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + AC_CHECK_LIB(dl, dlopen, [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_FUNC(dlopen, lt_cv_dlopen="dlopen", + [AC_CHECK_FUNC(shl_load, lt_cv_dlopen="shl_load", + [AC_CHECK_LIB(svld, dlopen, + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB(dld, shl_load, + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ;; + 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" + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + 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_AC_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 + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_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 +])# AC_LIBTOOL_DLOPEN_SELF + +AC_DEFUN([_LT_AC_LTCONFIG_HACK], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +[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' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" +need_locks="$enable_libtool_lock" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case $host_os in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +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 + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="[$]2" + +AC_MSG_CHECKING([for objdir]) +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +AC_MSG_RESULT($objdir) + + +AC_ARG_WITH(pic, +[ --with-pic try to use only PIC/non-PIC objects [default=use both]], +pic_mode="$withval", pic_mode=default) +test -z "$pic_mode" && pic_mode=default + +# We assume here that the value for lt_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +AC_MSG_CHECKING([for $compiler option to produce PIC]) +AC_CACHE_VAL(lt_cv_prog_cc_pic, +[ lt_cv_prog_cc_pic= + lt_cv_prog_cc_shlib= + lt_cv_prog_cc_wl= + lt_cv_prog_cc_static= + lt_cv_prog_cc_no_builtin= + lt_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$GCC" = yes; then + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-static' + + case $host_os in + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # we not sure about C++ programs. + lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" + ;; + amigaos*) + # 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_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + cygwin* | mingw* | pw32* | os2*) + # 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_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + lt_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix3* | aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better lt_cv_prog_cc_static that works with the bundled CC? + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" + lt_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6*) + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | pw32* | os2*) + # 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_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + lt_cv_prog_cc_pic='-Kpic' + lt_cv_prog_cc_static='-dn' + lt_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + lt_cv_prog_cc_pic='-PIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + if test "x$host_vendor" = xsni; then + lt_cv_prog_cc_wl='-LD' + else + lt_cv_prog_cc_wl='-Wl,' + fi + ;; + + uts4*) + lt_cv_prog_cc_pic='-pic' + lt_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_cv_prog_cc_pic='-Kconform_pic' + lt_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + lt_cv_prog_cc_can_build_shared=no + ;; + esac + fi +]) +if test -z "$lt_cv_prog_cc_pic"; then + AC_MSG_RESULT([none]) +else + AC_MSG_RESULT([$lt_cv_prog_cc_pic]) + + # Check to make sure the pic_flag actually works. + AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works]) + AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" + AC_TRY_COMPILE([], [], [dnl + case $host_os in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then + # they create non-PIC objects. So, if there were any warnings, we + # assume that PIC is not supported. + if test -s conftest.err; then + lt_cv_prog_cc_pic_works=no + else + lt_cv_prog_cc_pic_works=yes + fi + ;; + *) + lt_cv_prog_cc_pic_works=yes + ;; + esac + ], [dnl + lt_cv_prog_cc_pic_works=no + ]) + CFLAGS="$save_CFLAGS" + ]) + + if test "X$lt_cv_prog_cc_pic_works" = Xno; then + lt_cv_prog_cc_pic= + lt_cv_prog_cc_can_build_shared=no + else + lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" + fi + + AC_MSG_RESULT([$lt_cv_prog_cc_pic_works]) +fi + +# Check for any special shared library compilation flags. +if test -n "$lt_cv_prog_cc_shlib"; then + AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | [egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]"] >/dev/null; then : + else + AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure]) + lt_cv_prog_cc_can_build_shared=no + fi +fi + +AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works]) +AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl + lt_cv_prog_cc_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" + AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes]) + LDFLAGS="$save_LDFLAGS" +]) + +# Belt *and* braces to stop my trousers falling down: +test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= +AC_MSG_RESULT([$lt_cv_prog_cc_static_works]) + +pic_flag="$lt_cv_prog_cc_pic" +special_shlib_compile_flags="$lt_cv_prog_cc_shlib" +wl="$lt_cv_prog_cc_wl" +link_static_flag="$lt_cv_prog_cc_static" +no_builtin_flag="$lt_cv_prog_cc_no_builtin" +can_build_shared="$lt_cv_prog_cc_can_build_shared" + + +# Check to see if options -o and -c are simultaneously supported by compiler +AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext]) +AC_CACHE_VAL([lt_cv_compiler_c_o], [ +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +echo "int some_variable = 0;" > conftest.$ac_ext +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" +compiler_c_o=no +if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && 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 + if test -s out/conftest.err; then + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&AC_FD_CC + lt_cv_compiler_c_o=no +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null +]) +compiler_c_o=$lt_cv_compiler_c_o +AC_MSG_RESULT([$compiler_c_o]) + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + AC_MSG_CHECKING([if $compiler supports -c -o file.lo]) + AC_CACHE_VAL([lt_cv_compiler_o_lo], [ + lt_cv_compiler_o_lo=no + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + lt_cv_compiler_o_lo=no + else + lt_cv_compiler_o_lo=yes + fi + ]) + CFLAGS="$save_CFLAGS" + ]) + compiler_o_lo=$lt_cv_compiler_o_lo + AC_MSG_RESULT([$compiler_c_lo]) +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = 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 + +if test "$GCC" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions]) + echo "int some_variable = 0;" > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + compiler_rtti_exceptions=no + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + compiler_rtti_exceptions=no + else + compiler_rtti_exceptions=yes + fi + ]) + CFLAGS="$save_CFLAGS" + AC_MSG_RESULT([$compiler_rtti_exceptions]) + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi +fi + +# See if the linker supports building shared libraries. +AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries]) + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +old_archive_from_expsyms_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# 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 egrep regular expression 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_" +# 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. +extract_expsyms_cmds= + +case $host_os in +cygwin* | mingw* | pw32* ) + # 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 + ;; + +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX, the GNU linker is very broken + # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, 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 modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + 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 + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach 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*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < [$]0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + [sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//"] < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \[$]# in + 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + 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 -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&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. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + 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 + ;; + + 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 | egrep ': supported targets:.* elf' > /dev/null; then + 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 + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + esac + 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 "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + # 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_libdir_separator=':' + if test "$GCC" = yes; then + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + 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 + shared_flag='-shared' + else + if test "$host_cpu" = ia64; then + shared_flag='-G' + else + shared_flag='${wl}-bM:SRE' + fi + hardcode_direct=yes + fi + + 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 + # 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 run time linking. + aix_use_runtimelinking=no + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl" ); then + aix_use_runtimelinking=yes + break + fi + done + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + # It seems that -bexpall can do strange things, so it is better to + # generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + allow_undefined_flag=' -Wl,-G' + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-znodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, -berok will + # link without error, but may produce a broken library. + allow_undefined_flag='${wl}-berok" + # This is a bit strange, but is similar to how AIX traditionally builds + # it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' + fi + fi + ;; + + amigaos*) + 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 + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw* | pw32*) + # 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. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''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' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + allow_undefined_flag='-undefined suppress' + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + archive_cmds='$CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linkopts -install_name $rpath/$soname $(test -n "$verstring" -a x$verstring != x0.0 && echo $verstring)' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + freebsd1*) + ld_shlibs=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*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) 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' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + 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 $linkopts' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + 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" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + 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} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${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='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + #Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + 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 + ;; + + solaris*) + no_undefined_flag=' -z defs' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + 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' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + [solaris2.[0-5] | solaris2.[0-5].*]) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + 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) + if test "x$host_vendor" = xsno; then + archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_direct=yes # is this really true??? + else + 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 + fi + 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' + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + 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' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + 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.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi +AC_MSG_RESULT([$ld_shlibs]) +test "$ld_shlibs" = no && can_build_shared=no + +# Check hardcoding attributes. +AC_MSG_CHECKING([how to hardcode library paths into programs]) +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant 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 "$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 +AC_MSG_RESULT([$hardcode_action]) + +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 + AC_MSG_RESULT([no]) +fi + +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +# PORTME Fill in your ld.so characteristics +AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +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" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4* | aix5*) + version_type=linux + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + 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}.so$versuffix ${libname}${release}.so$major $libname.so' + 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}.so$major' + fi + shlibpath_var=LIBPATH + deplibs_check_method=pass_all + fi + ;; + +amigaos*) + 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=`$echo "X$lib" | [$Xsed -e '\''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' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$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" + export_dynamic_flag_spec=-rdynamic + # 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*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # 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 + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + 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. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6*) + version_type=irix + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' + case $host_os in + irix5*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") 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}" + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # 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 + + # 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' + ;; + +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}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$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 + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + need_version=no + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + 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" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$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}.so$versuffix ${libname}.so$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.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=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 + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +if test "$hardcode_action" = relink; 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 + +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 + +AC_LIBTOOL_DLOPEN_SELF + +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. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + AC_CACHE_VAL([lt_cv_archive_cmds_need_lc], + [$rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile); then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi]) + AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc]) + ;; + esac +fi +need_lc=${lt_cv_archive_cmds_need_lc-yes} + +# The second clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + : +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi + +if test -f "$ltmain"; then + trap "$rm \"${ofile}T\"; exit 1" 1 2 15 + $rm -f "${ofile}T" + + echo creating $ofile + + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS \ + AR AR_FLAGS CC LD LN_S NM SHELL \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ + postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ + old_striplib striplib file_magic_cmd export_symbols_cmds \ + deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case $var in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + cat <<__EOF__ > "${ofile}T" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996-2000 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 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 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# 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. + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# The default C compiler. +CC=$lt_CC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_pic_flag +pic_mode=$pic_mode + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$lt_compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# 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 + +# 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 + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_no_builtin_flag + +# 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 + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# 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 + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# 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 and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# 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 + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_global_symbol_to_cdecl + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# 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.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# 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 + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# 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 + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# 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 + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_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 + +# ### END LIBTOOL CONFIG + +__EOF__ + + case $host_os in + aix3*) + cat <<\EOF >> "${ofile}T" + +# 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 +EOF + ;; + esac + + case $host_os in + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "${ofile}T" + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# 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 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (dll < 1) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i> "${ofile}T" || (rm -f "${ofile}T"; exit 1) + + mv -f "${ofile}T" "$ofile" || \ + (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") + chmod +x "$ofile" +fi + +])# _LT_AC_LTCONFIG_HACK + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[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. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[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. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[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. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[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_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +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="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + 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 <&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 + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_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 +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])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 GCC]) + 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. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path 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 + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + 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 GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +# AC_PROG_LD_GNU - +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependant libraries], +lt_cv_deplibs_check_method, +[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 egrep 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 +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + [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* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[012]) + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + 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)/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 + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + [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_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + +irix5* | irix6*) + case $host_os in + irix5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + [lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"] + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | i*86 | powerpc* | sparc* | ia64* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;] + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'] + else + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'] + 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 + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +[sysv5uw[78]* | sysv4*uw2*)] + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + 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 + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}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 + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + 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 + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and INCLTDL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and INCLTDL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + INCLTDL= + fi +]) + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +dnl DPKG_CACHED_TRY_COMPILE(,,,,,) +define(DPKG_CACHED_TRY_COMPILE,[ + AC_MSG_CHECKING($1) + AC_CACHE_VAL($2,[ + AC_TRY_COMPILE([$3],[$4],[$2=yes],[$2=no]) + ]) + if test "x$$2" = xyes; then + true + $5 + else + true + $6 + fi +]) + +define(ADNS_C_GCCATTRIB,[ + DPKG_CACHED_TRY_COMPILE(__attribute__((,,)),adns_cv_c_attribute_supported,, + [extern int testfunction(int x) __attribute__((,,))], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GNUC25_ATTRIB) + DPKG_CACHED_TRY_COMPILE(__attribute__((noreturn)),adns_cv_c_attribute_noreturn,, + [extern int testfunction(int x) __attribute__((noreturn))], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GNUC25_NORETURN), + AC_MSG_RESULT(no)) + DPKG_CACHED_TRY_COMPILE(__attribute__((const)),adns_cv_c_attribute_const,, + [extern int testfunction(int x) __attribute__((const))], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GNUC25_CONST), + AC_MSG_RESULT(no)) + DPKG_CACHED_TRY_COMPILE(__attribute__((format...)),adns_cv_attribute_format,, + [extern int testfunction(char *y, ...) __attribute__((format(printf,1,2)))], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GNUC25_PRINTFFORMAT), + AC_MSG_RESULT(no)), + AC_MSG_RESULT(no)) +]) + +define(ADNS_C_GETFUNC,[ + AC_CHECK_FUNC([$1],,[ + AC_CHECK_LIB([$2],[$1],[$3],[ + AC_MSG_ERROR([cannot find library function $1]) + ]) + ]) +]) +dnl +dnl NEO_SUBDIR_CONFIG(dir [, sub-package-cmdline-args]) +dnl +dnl Note that this code is a direct copy of that which is found in +dnl the apr project's build/apr_common.m4. +AC_DEFUN(NEO_SUBDIR_CONFIG, [ + # save our work to this point; this allows the sub-package to use it + AC_CACHE_SAVE + + echo + echo "----------------------------------------------------------------" + echo "configuring package in $1 now" + echo "----------------------------------------------------------------" + ac_popdir=`pwd` + ac_abs_srcdir=`(cd $srcdir/$1 && pwd)` + apr_config_subdirs="$1" + test -d $1 || $MKDIR $1 + cd $1 + + #changequote(, )dnl + # A "../" for each directory in /$config_subdirs. + #ac_dots=`echo $apr_config_subdirs|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` + #changequote([, ])dnl + + # Make the cache file name correct relative to the subdirectory. + case "$cache_file" in + /*) ac_sub_cache_file=$cache_file ;; + *) # Relative path. + ac_sub_cache_file="$ac_dots$cache_file" ;; + esac + + # The eval makes quoting arguments work. + if eval $ac_abs_srcdir/configure $ac_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_abs_srcdir $2 + then : + echo "$1 configured properly" + else + echo "configure failed for $1" + exit 1 + fi + cd $ac_popdir + + # grab any updates from the sub-package + AC_CACHE_LOAD +])dnl diff --git a/adns/Makefile b/adns/Makefile new file mode 100644 index 0000000..e65ebfe --- /dev/null +++ b/adns/Makefile @@ -0,0 +1,43 @@ + +INCLUDES = -I.. + +SRCS = check.c event.c general.c parse.c query.c reply.c setup.c transmit.c types.c +OBJS = ${SRCS:.c=.o} + +all: $(OBJS) + +modules: $(OBJS) + +.c.o: + $(CC) $(CFLAGS) $(INCLUDES) -c $< + +clean: + $(RM) *.o *.lo *.so *.a *.exe config.h + +distclean: + $(RM) *.o *.lo *.so *.a *.exe config.h + +depend: + $(CC) -MM $(INCLUDES) $(CFLAGS) $(SRCS) > .depend + +install: + $(INSTALL_DATA) adns.h $(INCDIRECTORY) + +DISTFILES =*.c adns.h dlist.h internal.h tvarith.h Makefile *.in + +dist: + @for file in $(DISTFILES); do \ + cp -pr $$file $(DISTDIR)/$$file; \ + done + +$(OBJS): Makefile + +check.o: check.c internal.h config.h adns.h dlist.h +event.o: event.c internal.h config.h adns.h dlist.h tvarith.h +general.o: general.c internal.h config.h adns.h dlist.h +parse.o: parse.c internal.h config.h adns.h dlist.h +query.o: query.c internal.h config.h adns.h dlist.h +reply.o: reply.c internal.h config.h adns.h dlist.h +setup.o: setup.c internal.h config.h adns.h dlist.h +transmit.o: transmit.c internal.h config.h adns.h dlist.h tvarith.h +types.o: types.c internal.h config.h adns.h dlist.h \ No newline at end of file diff --git a/adns/adns.h b/adns/adns.h new file mode 100644 index 0000000..da122f2 --- /dev/null +++ b/adns/adns.h @@ -0,0 +1,873 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + +/* + * adns.h + * - adns user-visible API (single-threaded, without any locking) + */ +/* + * + * This file is + * Copyright (C) 1997-2000 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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. + * + * + * For the benefit of certain LGPL'd `omnibus' software which + * provides a uniform interface to various things including adns, I + * make the following additional licence. I do this because the GPL + * would otherwise force either the omnibus software to be GPL'd or + * the adns-using part to be distributed separately. + * + * So: you may also redistribute and/or modify adns.h (but only the + * public header file adns.h and not any other part of adns) under the + * terms of the GNU Library General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Note that adns itself is GPL'd. Authors of adns-using applications + * with GPL-incompatible licences, and people who distribute adns with + * applications where the whole distribution is not GPL'd, are still + * likely to be in violation of the GPL. Anyone who wants to do this + * should contact Ian Jackson. Please note that to avoid encouraging + * people to infringe the GPL as it applies to the body of adns, Ian + * thinks that if you take advantage of the special exception to + * redistribute just adns.h under the LGPL, you should retain this + * paragraph in its place in the appropriate copyright statements. + * + * + * You should have received a copy of the GNU General Public License, + * or the GNU Library General Public License, as appropriate, along + * with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * $Id$ + */ + +#ifndef ADNS_H_INCLUDED +#define ADNS_H_INCLUDED + +#include + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { /* I really dislike this - iwj. */ +#endif + +/* All struct in_addr anywhere in adns are in NETWORK byte order. */ + + typedef struct adns__state *adns_state; + typedef struct adns__query *adns_query; + + typedef enum { + adns_if_noenv = 0x0001, /* do not look at environment */ + adns_if_noerrprint = 0x0002, /* never print output to stderr (_debug overrides) */ + adns_if_noserverwarn = 0x0004, /* do not warn to stderr about duff nameservers etc */ + adns_if_debug = 0x0008, /* enable all output to stderr plus debug msgs */ + adns_if_logpid = 0x0080, /* include pid in diagnostic output */ + adns_if_noautosys = 0x0010, /* do not make syscalls at every opportunity */ + adns_if_eintr = 0x0020, /* allow _wait and _synchronous to return EINTR */ + adns_if_nosigpipe = 0x0040, /* applic has SIGPIPE set to SIG_IGN, do not protect */ + adns_if_checkc_entex = 0x0100, /* do consistency checks on entry/exit to adns funcs */ + adns_if_checkc_freq = 0x0300 /* do consistency checks very frequently (slow!) */ + } adns_initflags; + + typedef enum { + adns_qf_search = 0x00000001, /* use the searchlist */ + adns_qf_usevc = 0x00000002, /* use a virtual circuit (TCP connection) */ + adns_qf_owner = 0x00000004, /* fill in the owner field in the answer */ + adns_qf_quoteok_query = 0x00000010, /* allow special chars in query domain */ + adns_qf_quoteok_cname = 0x00000000, /* allow ... in CNAME we go via - now default */ + adns_qf_quoteok_anshost = 0x00000040, /* allow ... in things supposed to be hostnames */ + adns_qf_quotefail_cname = 0x00000080, /* refuse if quote-req chars in CNAME we go via */ + adns_qf_cname_loose = 0x00000100, /* allow refs to CNAMEs - without, get _s_cname */ + adns_qf_cname_forbid = 0x00000200, /* don't follow CNAMEs, instead give _s_cname */ + adns__qf_internalmask = 0x0ff00000 + } adns_queryflags; + + typedef enum { + adns__rrt_typemask = 0x0ffff, + adns__qtf_deref = 0x10000, /* dereference domains and perhaps produce extra data */ + adns__qtf_mail822 = 0x20000, /* make mailboxes be in RFC822 rcpt field format */ + + adns_r_none = 0, + + adns_r_a = 1, + + adns_r_ns_raw = 2, + adns_r_ns = adns_r_ns_raw | adns__qtf_deref, + + adns_r_cname = 5, + + adns_r_soa_raw = 6, + adns_r_soa = adns_r_soa_raw | adns__qtf_mail822, + + adns_r_ptr_raw = 12, + adns_r_ptr = adns_r_ptr_raw | adns__qtf_deref, + + adns_r_hinfo = 13, + + adns_r_mx_raw = 15, + adns_r_mx = adns_r_mx_raw | adns__qtf_deref, + + adns_r_txt = 16, + + adns_r_rp_raw = 17, + adns_r_rp = adns_r_rp_raw | adns__qtf_mail822, + + adns_r_addr = adns_r_a | adns__qtf_deref + } adns_rrtype; + +/* + * In queries without qf_quoteok_*, all domains must have standard + * legal syntax, or you get adns_s_querydomainvalid (if the query + * domain contains bad characters) or adns_s_answerdomaininvalid (if + * the answer contains bad characters). + * + * In queries _with_ qf_quoteok_*, domains in the query or response + * may contain any characters, quoted according to RFC1035 5.1. On + * input to adns, the char* is a pointer to the interior of a " + * delimited string, except that " may appear in it unquoted. On + * output, the char* is a pointer to a string which would be legal + * either inside or outside " delimiters; any character which isn't + * legal in a hostname (ie alphanumeric or hyphen) or one of _ / + + * (the three other punctuation characters commonly abused in domain + * names) will be quoted, as \X if it is a printing ASCII character or + * \DDD otherwise. + * + * If the query goes via a CNAME then the canonical name (ie, the + * thing that the CNAME record refers to) is usually allowed to + * contain any characters, which will be quoted as above. With + * adns_qf_quotefail_cname you get adns_s_answerdomaininvalid when + * this happens. (This is a change from version 0.4 and earlier, in + * which failing the query was the default, and you had to say + * adns_qf_quoteok_cname to avoid this; that flag is now deprecated.) + * + * In version 0.4 and earlier, asking for _raw records containing + * mailboxes without specifying _qf_quoteok_anshost was silly. This + * is no longer the case. In this version only parts of responses + * that are actually supposed to be hostnames will be refused by + * default if quote-requiring characters are found. + */ + +/* + * If you ask for an RR which contains domains which are actually + * encoded mailboxes, and don't ask for the _raw version, then adns + * returns the mailbox formatted suitably for an RFC822 recipient + * header field. The particular format used is that if the mailbox + * requires quoting according to the rules in RFC822 then the + * local-part is quoted in double quotes, which end at the next + * unescaped double quote (\ is the escape char, and is doubled, and + * is used to escape only \ and "). If the local-part is legal + * without quoting according to RFC822, it is presented as-is. In any + * case the local-part is followed by an @ and the domain. The domain + * will not contain any characters not legal in hostnames. + * + * Unquoted local-parts may contain any printing 7-bit ASCII + * except the punctuation characters ( ) < > @ , ; : \ " [ ] + * I.e. they may contain alphanumerics, and the following + * punctuation characters: ! # % ^ & * - _ = + { } . + * + * adns will reject local parts containing control characters (byte + * values 0-31, 127-159, and 255) - these appear to be legal according + * to RFC822 (at least 0-127) but are clearly a bad idea. RFC1035 + * syntax does not make any distinction between a single RFC822 + * quoted-string containing full stops, and a series of quoted-strings + * separated by full stops; adns will return anything that isn't all + * valid atoms as a single quoted-string. RFC822 does not allow + * high-bit-set characters at all, but adns does allow them in + * local-parts, treating them as needing quoting. + * + * If you ask for the domain with _raw then _no_ checking is done + * (even on the host part, regardless of adns_qf_quoteok_anshost), and + * you just get the domain name in master file format. + * + * If no mailbox is supplied the returned string will be `.' in either + * case. + */ + + typedef enum { + adns_s_ok, + + /* locally induced errors */ + adns_s_nomemory, + adns_s_unknownrrtype, + adns_s_systemfail, + + adns_s_max_localfail = 29, + + /* remotely induced errors, detected locally */ + adns_s_timeout, + adns_s_allservfail, + adns_s_norecurse, + adns_s_invalidresponse, + adns_s_unknownformat, + + adns_s_max_remotefail = 59, + + /* remotely induced errors, reported by remote server to us */ + adns_s_rcodeservfail, + adns_s_rcodeformaterror, + adns_s_rcodenotimplemented, + adns_s_rcoderefused, + adns_s_rcodeunknown, + + adns_s_max_tempfail = 99, + + /* remote configuration errors */ + adns_s_inconsistent, /* PTR gives domain whose A does not exist and match */ + adns_s_prohibitedcname, /* CNAME found where eg A expected (not if _qf_loosecname) */ + adns_s_answerdomaininvalid, + adns_s_answerdomaintoolong, + adns_s_invaliddata, + + adns_s_max_misconfig = 199, + + /* permanent problems with the query */ + adns_s_querydomainwrong, + adns_s_querydomaininvalid, + adns_s_querydomaintoolong, + + adns_s_max_misquery = 299, + + /* permanent errors */ + adns_s_nxdomain, + adns_s_nodata, + + adns_s_max_permfail = 499 + } adns_status; + + typedef struct { + int len; + union { + struct sockaddr sa; + struct sockaddr_in inet; + } addr; + } adns_rr_addr; + + typedef struct { + char *host; + adns_status astatus; + int naddrs; /* temp fail => -1, perm fail => 0, s_ok => >0 */ + adns_rr_addr *addrs; + } adns_rr_hostaddr; + + typedef struct { + char *(array[2]); + } adns_rr_strpair; + + typedef struct { + int i; + adns_rr_hostaddr ha; + } adns_rr_inthostaddr; + + typedef struct { + /* Used both for mx_raw, in which case i is the preference and str the domain, + * and for txt, in which case each entry has i for the `text' length, + * and str for the data (which will have had an extra nul appended + * so that if it was plain text it is now a null-terminated string). + */ + int i; + char *str; + } adns_rr_intstr; + + typedef struct { + adns_rr_intstr array[2]; + } adns_rr_intstrpair; + + typedef struct { + char *mname, *rname; + unsigned long serial, refresh, retry, expire, minimum; + } adns_rr_soa; + + typedef struct { + adns_status status; + char *cname; /* always NULL if query was for CNAME records */ + char *owner; /* only set if requested in query flags, and may be 0 on error anyway */ + adns_rrtype type; /* guaranteed to be same as in query */ + time_t expires; /* expiry time, defined only if _s_ok, nxdomain or nodata. NOT TTL! */ + int nrrs, rrsz; /* nrrs is 0 if an error occurs */ + union { + void *untyped; + unsigned char *bytes; + char *(*str); /* ns_raw, cname, ptr, ptr_raw */ + adns_rr_intstr *(*manyistr); /* txt (list of strings ends with i=-1, str=0) */ + adns_rr_addr *addr; /* addr */ + struct in_addr *inaddr; /* a */ + adns_rr_hostaddr *hostaddr; /* ns */ + adns_rr_intstrpair *intstrpair; /* hinfo */ + adns_rr_strpair *strpair; /* rp, rp_raw */ + adns_rr_inthostaddr *inthostaddr; /* mx */ + adns_rr_intstr *intstr; /* mx_raw */ + adns_rr_soa *soa; /* soa, soa_raw */ + } rrs; + } adns_answer; + +/* Memory management: + * adns_state and adns_query are actually pointers to malloc'd state; + * On submission questions are copied, including the owner domain; + * Answers are malloc'd as a single piece of memory; pointers in the + * answer struct point into further memory in the answer. + * query_io: + * Must always be non-null pointer; + * If *query_io is 0 to start with then any query may be returned; + * If *query_io is !0 adns_query then only that query may be returned. + * If the call is successful, *query_io, *answer_r, and *context_r + * will all be set. + * Errors: + * Return values are 0 or an errno value. + * + * For _init, _init_strcfg, _submit and _synchronous, system errors + * (eg, failure to create sockets, malloc failure, etc.) return errno + * values. + * + * For _wait and _check failures are reported in the answer + * structure, and only 0, ESRCH or (for _check) EAGAIN is + * returned: if no (appropriate) requests are done adns_check returns + * EAGAIN; if no (appropriate) requests are outstanding both + * adns_query and adns_wait return ESRCH. + * + * Additionally, _wait can return EINTR if you set adns_if_eintr. + * + * All other errors (nameserver failure, timed out connections, &c) + * are returned in the status field of the answer. After a + * successful _wait or _check, if status is nonzero then nrrs will be + * 0, otherwise it will be >0. type will always be the type + * requested. + */ + + int adns_init(adns_state * newstate_r, adns_initflags flags, + FILE * diagfile /*0=>stderr */ ); + + int adns_init_strcfg(adns_state * newstate_r, adns_initflags flags, + FILE * diagfile /*0=>discard */ , + const char *configtext); + +/* Configuration: + * adns_init reads /etc/resolv.conf, which is expected to be (broadly + * speaking) in the format expected by libresolv, and then + * /etc/resolv-adns.conf if it exists. adns_init_strcfg is instead + * passed a string which is interpreted as if it were the contents of + * resolv.conf or resolv-adns.conf. In general, configuration which + * is set later overrides any that is set earlier. + * + * Standard directives understood in resolv[-adns].conf: + * + * nameserver
+ * Must be followed by the IP address of a nameserver. Several + * nameservers may be specified, and they will be tried in the order + * found. There is a compiled in limit, currently 5, on the number + * of nameservers. (libresolv supports only 3 nameservers.) + * + * search ... + * Specifies the search list for queries which specify + * adns_qf_search. This is a list of domains to append to the query + * domain. The query domain will be tried as-is either before all + * of these or after them, depending on the ndots option setting + * (see below). + * + * domain + * This is present only for backward compatibility with obsolete + * versions of libresolv. It should not be used, and is interpreted + * by adns as if it were `search' - note that this is subtly + * different to libresolv's interpretation of this directive. + * + * sortlist / ... + * Should be followed by a sequence of IP-address and netmask pairs, + * separated by spaces. They may be specified as + * eg. 172.30.206.0/24 or 172.30.206.0/255.255.255.0. Currently up + * to 15 pairs may be specified (but note that libresolv only + * supports up to 10). + * + * options + * Should followed by one or more options, separated by spaces. + * Each option consists of an option name, followed by optionally + * a colon and a value. Options are listed below. + * + * Non-standard directives understood in resolv[-adns].conf: + * + * clearnameservers + * Clears the list of nameservers, so that further nameserver lines + * start again from the beginning. + * + * include + * The specified file will be read. + * + * Additionally, adns will ignore lines in resolv[-adns].conf which + * start with a #. + * + * Standard options understood: + * + * debug + * Enables debugging output from the resolver, which will be written + * to stderr. + * + * ndots: + * Affects whether queries with adns_qf_search will be tried first + * without adding domains from the searchlist, or whether the bare + * query domain will be tried last. Queries which contain at least + * dots will be tried bare first. The default is 1. + * + * Non-standard options understood: + * + * adns_checkc:none + * adns_checkc:entex + * adns_checkc:freq + * Changes the consistency checking frequency; this overrides the + * setting of adns_if_check_entex, adns_if_check_freq, or neither, + * in the flags passed to adns_init. + * + * There are a number of environment variables which can modify the + * behaviour of adns. They take effect only if adns_init is used, and + * the caller of adns_init can disable them using adns_if_noenv. In + * each case there is both a FOO and an ADNS_FOO; the latter is + * interpreted later so that it can override the former. Unless + * otherwise stated, environment variables are interpreted after + * resolv[-adns].conf are read, in the order they are listed here. + * + * RES_CONF, ADNS_RES_CONF + * A filename, whose contets are in the format of resolv.conf. + * + * RES_CONF_TEXT, ADNS_RES_CONF_TEXT + * A string in the format of resolv.conf. + * + * RES_OPTIONS, ADNS_RES_OPTIONS + * These are parsed as if they appeared in the `options' line of a + * resolv.conf. In addition to being parsed at this point in the + * sequence, they are also parsed at the very beginning before + * resolv.conf or any other environment variables are read, so that + * any debug option can affect the processing of the configuration. + * + * LOCALDOMAIN, ADNS_LOCALDOMAIN + * These are interpreted as if their contents appeared in a `search' + * line in resolv.conf. + */ + + int adns_synchronous(adns_state ads, + const char *owner, + adns_rrtype type, + adns_queryflags flags, + adns_answer ** answer_r); + +/* NB: if you set adns_if_noautosys then _submit and _check do not + * make any system calls; you must use some of the asynch-io event + * processing functions to actually get things to happen. + */ + + int adns_submit(adns_state ads, + const char *owner, + adns_rrtype type, + adns_queryflags flags, + void *context, adns_query * query_r); + +/* The owner should be quoted in master file format. */ + + int adns_check(adns_state ads, + adns_query * query_io, + adns_answer ** answer_r, void **context_r); + + int adns_wait(adns_state ads, + adns_query * query_io, + adns_answer ** answer_r, void **context_r); + +/* same as adns_wait but uses poll(2) internally */ + int adns_wait_poll(adns_state ads, + adns_query * query_io, + adns_answer ** answer_r, void **context_r); + + void adns_cancel(adns_query query); + +/* The adns_query you get back from _submit is valid (ie, can be + * legitimately passed into adns functions) until it is returned by + * adns_check or adns_wait, or passed to adns_cancel. After that it + * must not be used. You can rely on it not being reused until the + * first adns_submit or _transact call using the same adns_state after + * it became invalid, so you may compare it for equality with other + * query handles until you next call _query or _transact. + * + * _submit and _synchronous return ENOSYS if they don't understand the + * query type. + */ + + int adns_submit_reverse(adns_state ads, + const struct sockaddr *addr, + adns_rrtype type, + adns_queryflags flags, + void *context, adns_query * query_r); +/* type must be _r_ptr or _r_ptr_raw. _qf_search is ignored. + * addr->sa_family must be AF_INET or you get ENOSYS. + */ + + int adns_submit_reverse_any(adns_state ads, + const struct sockaddr *addr, + const char *rzone, + adns_rrtype type, + adns_queryflags flags, + void *context, adns_query * query_r); +/* For RBL-style reverse `zone's; look up + * . + * Any type is allowed. _qf_search is ignored. + * addr->sa_family must be AF_INET or you get ENOSYS. + */ + + void adns_finish(adns_state ads); +/* You may call this even if you have queries outstanding; + * they will be cancelled. + */ + + + void adns_forallqueries_begin(adns_state ads); + adns_query adns_forallqueries_next(adns_state ads, + void **context_r); +/* Iterator functions, which you can use to loop over the outstanding + * (submitted but not yet successfuly checked/waited) queries. + * + * You can only have one iteration going at once. You may call _begin + * at any time; after that, an iteration will be in progress. You may + * only call _next when an iteration is in progress - anything else + * may coredump. The iteration remains in progress until _next + * returns 0, indicating that all the queries have been walked over, + * or ANY other adns function is called with the same adns_state (or a + * query in the same adns_state). There is no need to explicitly + * finish an iteration. + * + * context_r may be 0. *context_r may not be set when _next returns 0. + */ + + void adns_checkconsistency(adns_state ads, adns_query qu); +/* Checks the consistency of adns's internal data structures. + * If any error is found, the program will abort(). + * You may pass 0 for qu; if you pass non-null then additional checks + * are done to make sure that qu is a valid query. + */ + +/* + * Example expected/legal calling sequence for submit/check/wait: + * adns_init + * adns_submit 1 + * adns_submit 2 + * adns_submit 3 + * adns_wait 1 + * adns_check 3 -> EAGAIN + * adns_wait 2 + * adns_wait 3 + * .... + * adns_finish + */ + +/* + * Entrypoints for generic asynch io: + * (these entrypoints are not very useful except in combination with * + * some of the other I/O model calls which can tell you which fds to + * be interested in): + * + * Note that any adns call may cause adns to open and close fds, so + * you must call beforeselect or beforepoll again just before + * blocking, or you may not have an up-to-date list of it's fds. + */ + + int adns_processany(adns_state ads); +/* Gives adns flow-of-control for a bit. This will never block, and + * can be used with any threading/asynch-io model. If some error + * occurred which might cause an event loop to spin then the errno + * value is returned. + */ + + int adns_processreadable(adns_state ads, int fd, + const struct timeval *now); + int adns_processwriteable(adns_state ads, int fd, + const struct timeval *now); + int adns_processexceptional(adns_state ads, int fd, + const struct timeval *now); +/* Gives adns flow-of-control so that it can process incoming data + * from, or send outgoing data via, fd. Very like _processany. If it + * returns zero then fd will no longer be readable or writeable + * (unless of course more data has arrived since). adns will _only_ + * use that fd and only in the manner specified, regardless of whether + * adns_if_noautosys was specified. + * + * adns_processexceptional should be called when select(2) reports an + * exceptional condition, or poll(2) reports POLLPRI. + * + * It is fine to call _processreabable or _processwriteable when the + * fd is not ready, or with an fd that doesn't belong to adns; it will + * then just return 0. + * + * If some error occurred which might prevent an event loop to spin + * then the errno value is returned. + */ + + void adns_processtimeouts(adns_state ads, + const struct timeval *now); +/* Gives adns flow-of-control so that it can process any timeouts + * which might have happened. Very like _processreadable/writeable. + * + * now may be 0; if it isn't, *now must be the current time, recently + * obtained from gettimeofday. + */ + + void adns_firsttimeout(adns_state ads, + struct timeval **tv_mod, + struct timeval *tv_buf, struct timeval now); +/* Asks adns when it would first like the opportunity to time + * something out. now must be the current time, from gettimeofday. + * + * If tv_mod points to 0 then tv_buf must be non-null, and + * _firsttimeout will fill in *tv_buf with the time until the first + * timeout, and make *tv_mod point to tv_buf. If adns doesn't have + * anything that might need timing out it will leave *tv_mod as 0. + * + * If *tv_mod is not 0 then tv_buf is not used. adns will update + * *tv_mod if it has any earlier timeout, and leave it alone if it + * doesn't. + * + * This call will not actually do any I/O, or change the fds that adns + * is using. It always succeeds and never blocks. + */ + + void adns_globalsystemfailure(adns_state ads); +/* If serious problem(s) happen which globally affect your ability to + * interact properly with adns, or adns's ability to function + * properly, you or adns can call this function. + * + * All currently outstanding queries will be made to fail with + * adns_s_systemfail, and adns will close any stream sockets it has + * open. + * + * This is used by adns, for example, if gettimeofday() fails. + * Without this the program's event loop might start to spin ! + * + * This call will never block. + */ + +/* + * Entrypoints for select-loop based asynch io: + */ + + void adns_beforeselect(adns_state ads, int *maxfd, + fd_set * readfds, fd_set * writefds, + fd_set * exceptfds, struct timeval **tv_mod, + struct timeval *tv_buf, + const struct timeval *now); +/* Find out file descriptors adns is interested in, and when it would + * like the opportunity to time something out. If you do not plan to + * block then tv_mod may be 0. Otherwise, tv_mod and tv_buf are as + * for adns_firsttimeout. readfds, writefds, exceptfds and maxfd_io may + * not be 0. + * + * If now is not 0 then this will never actually do any I/O, or change + * the fds that adns is using or the timeouts it wants. In any case + * it won't block, and it will set the timeout to zero if a query + * finishes in _beforeselect. + */ + + void adns_afterselect(adns_state ads, int maxfd, + const fd_set * readfds, + const fd_set * writefds, + const fd_set * exceptfds, + const struct timeval *now); +/* Gives adns flow-of-control for a bit; intended for use after + * select. This is just a fancy way of calling adns_processreadable/ + * writeable/timeouts as appropriate, as if select had returned the + * data being passed. Always succeeds. + */ + +/* + * Example calling sequence: + * + * adns_init _noautosys + * loop { + * adns_beforeselect + * select + * adns_afterselect + * ... + * adns_submit / adns_check + * ... + * } + */ + +/* + * Entrypoints for poll-loop based asynch io: + */ + + struct pollfd; +/* In case your system doesn't have it or you forgot to include + * , to stop the following declarations from causing + * problems. If your system doesn't have poll then the following + * entrypoints will not be defined in libadns. Sorry ! + */ + + int adns_beforepoll(adns_state ads, struct pollfd *fds, + int *nfds_io, int *timeout_io, + const struct timeval *now); +/* Finds out which fd's adns is interested in, and when it would like + * to be able to time things out. This is in a form suitable for use + * with poll(2). + * + * On entry, usually fds should point to at least *nfds_io structs. + * adns will fill up to that many structs will information for poll, + * and record in *nfds_io how many structs it filled. If it wants to + * listen for more structs then *nfds_io will be set to the number + * required and _beforepoll will return ERANGE. + * + * You may call _beforepoll with fds==0 and *nfds_io 0, in which case + * adns will fill in the number of fds that it might be interested in + * in *nfds_io, and always return either 0 (if it is not interested in + * any fds) or ERANGE (if it is). + * + * NOTE that (unless now is 0) adns may acquire additional fds + * from one call to the next, so you must put adns_beforepoll in a + * loop, rather than assuming that the second call (with the buffer + * size requested by the first) will not return ERANGE. + * + * adns only ever sets POLLIN, POLLOUT and POLLPRI in its pollfd + * structs, and only ever looks at those bits. POLLPRI is required to + * detect TCP Urgent Data (which should not be used by a DNS server) + * so that adns can know that the TCP stream is now useless. + * + * In any case, *timeout_io should be a timeout value as for poll(2), + * which adns will modify downwards as required. If the caller does + * not plan to block then *timeout_io should be 0 on entry, or + * alternatively, timeout_io may be 0. (Alternatively, the caller may + * use _beforeselect with timeout_io==0 to find out about file + * descriptors, and use _firsttimeout is used to find out when adns + * might want to time something out.) + * + * adns_beforepoll will return 0 on success, and will not fail for any + * reason other than the fds buffer being too small (ERANGE). + * + * This call will never actually do any I/O. If you supply the + * current time it will not change the fds that adns is using or the + * timeouts it wants. + * + * In any case this call won't block. + */ + +#define ADNS_POLLFDS_RECOMMENDED 2 +/* If you allocate an fds buf with at least RECOMMENDED entries then + * you are unlikely to need to enlarge it. You are recommended to do + * so if it's convenient. However, you must be prepared for adns to + * require more space than this. + */ + + void adns_afterpoll(adns_state ads, const struct pollfd *fds, + int nfds, const struct timeval *now); +/* Gives adns flow-of-control for a bit; intended for use after + * poll(2). fds and nfds should be the results from poll(). pollfd + * structs mentioning fds not belonging to adns will be ignored. + */ + + + adns_status adns_rr_info(adns_rrtype type, + const char **rrtname_r, + const char **fmtname_r, int *len_r, + const void *datap, char **data_r); +/* + * Get information about a query type, or convert reply data to a + * textual form. type must be specified, and the official name of the + * corresponding RR type will be returned in *rrtname_r, and + * information about the processing style in *fmtname_r. The length + * of the table entry in an answer for that type will be returned in + * in *len_r. Any or all of rrtname_r, fmtname_r and len_r may be 0. + * If fmtname_r is non-null then *fmtname_r may be null on return, + * indicating that no special processing is involved. + * + * data_r be must be non-null iff datap is. In this case *data_r will + * be set to point to a string pointing to a representation of the RR + * data in master file format. (The owner name, timeout, class and + * type will not be present - only the data part of the RR.) The + * memory will have been obtained from malloc() and must be freed by + * the caller. + * + * Usually this routine will succeed. Possible errors include: + * adns_s_nomemory + * adns_s_rrtypeunknown + * adns_s_invaliddata (*datap contained garbage) + * If an error occurs then no memory has been allocated, + * and *rrtname_r, *fmtname_r, *len_r and *data_r are undefined. + * + * There are some adns-invented data formats which are not official + * master file formats. These include: + * + * Mailboxes if __qtf_mail822: these are just included as-is. + * + * Addresses (adns_rr_addr): these may be of pretty much any type. + * The representation is in two parts: first, a word for the address + * family (ie, in AF_XXX, the XXX), and then one or more items for the + * address itself, depending on the format. For an IPv4 address the + * syntax is INET followed by the dotted quad (from inet_ntoa). + * Currently only IPv4 is supported. + * + * Text strings (as in adns_rr_txt) appear inside double quotes, and + * use \" and \\ to represent " and \, and \xHH to represent + * characters not in the range 32-126. + * + * Hostname with addresses (adns_rr_hostaddr): this consists of the + * hostname, as usual, followed by the adns_status value, as an + * abbreviation, and then a descriptive string (encoded as if it were + * a piece of text), for the address lookup, followed by zero or more + * addresses enclosed in ( and ). If the result was a temporary + * failure, then a single ? appears instead of the ( ). If the + * result was a permanent failure then an empty pair of parentheses + * appears (which a space in between). For example, one of the NS + * records for greenend.org.uk comes out like + * ns.chiark.greenend.org.uk ok "OK" ( INET 195.224.76.132 ) + * an MX referring to a nonexistent host might come out like: + * 50 sun2.nsfnet-relay.ac.uk nxdomain "No such domain" ( ) + * and if nameserver information is not available you might get: + * dns2.spong.dyn.ml.org timeout "DNS query timed out" ? + */ + + const char *adns_strerror(adns_status st); + const char *adns_errabbrev(adns_status st); + const char *adns_errtypeabbrev(adns_status st); +/* Like strerror but for adns_status values. adns_errabbrev returns + * the abbreviation of the error - eg, for adns_s_timeout it returns + * "timeout". adns_errtypeabbrev returns the abbreviation of the + * error class: ie, for values up to adns_s_max_XXX it will return the + * string XXX. You MUST NOT call these functions with status values + * not returned by the same adns library. + */ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif +#endif diff --git a/adns/check.c b/adns/check.c new file mode 100644 index 0000000..6e99426 --- /dev/null +++ b/adns/check.c @@ -0,0 +1,231 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * check.c + * - consistency checks + */ +/* + * This file is + * Copyright (C) 1997-1999 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "internal.h" +#include +void adns_checkconsistency(adns_state ads, adns_query qu) +{ + adns__consistency(ads, qu, cc_user); +} + +#define DLIST_CHECK(list, nodevar, part, body) \ + if ((list).head) { \ + assert(! (list).head->part back); \ + for ((nodevar)= (list).head; (nodevar); (nodevar)= (nodevar)->part next) { \ + assert((nodevar)->part next \ + ? (nodevar) == (nodevar)->part next->part back \ + : (nodevar) == (list).tail); \ + body \ + } \ + } + +#define DLIST_ASSERTON(node, nodevar, list, part) \ + do { \ + for ((nodevar)= (list).head; \ + (nodevar) != (node); \ + (nodevar)= (nodevar)->part next) { \ + assert((nodevar)); \ + } \ + } while(0) + +static void checkc_query_alloc(adns_state ads, adns_query qu) +{ + allocnode *an; + + DLIST_CHECK(qu->allocations, an,, { + }); +} + +static void checkc_query(adns_state ads, adns_query qu) +{ + adns_query child; + + assert(qu->udpnextserver < ads->nservers); + assert(!(qu->udpsent & (~0UL << ads->nservers))); + assert(qu->search_pos <= ads->nsearchlist); + if (qu->parent) + DLIST_ASSERTON(qu, child, qu->parent->children, siblings.); +} + +static void checkc_notcpbuf(adns_state ads) +{ + assert(!ads->tcpsend.used); + assert(!ads->tcprecv.used); + assert(!ads->tcprecv_skip); +} + +static void checkc_global(adns_state ads) +{ + int i; + + assert(ads->udpsocket >= 0); + + for (i = 0; i < ads->nsortlist; i++) + assert(! + (ads->sortlist[i].base.s_addr & ~ads->sortlist[i]. + mask.s_addr)); + + assert(ads->tcpserver >= 0 && ads->tcpserver < ads->nservers); + + switch (ads->tcpstate) { + case server_connecting: + assert(ads->tcpsocket >= 0); + checkc_notcpbuf(ads); + break; + case server_disconnected: + case server_broken: + assert(ads->tcpsocket == -1); + checkc_notcpbuf(ads); + break; + case server_ok: + assert(ads->tcpsocket >= 0); + assert(ads->tcprecv_skip <= ads->tcprecv.used); + break; + default: + assert(!"ads->tcpstate value"); + } + + assert(ads->searchlist || !ads->nsearchlist); +} + +static void checkc_queue_udpw(adns_state ads) +{ + adns_query qu; + + DLIST_CHECK(ads->udpw, qu,, { + assert(qu->state == query_tosend); + assert(qu->retries <= UDPMAXRETRIES); + assert(qu->udpsent); + assert(!qu->children.head && !qu->children.tail); + checkc_query(ads, qu); checkc_query_alloc(ads, qu);}); +} + +static void checkc_queue_tcpw(adns_state ads) +{ + adns_query qu; + + DLIST_CHECK(ads->tcpw, qu,, { + assert(qu->state == query_tcpw); + assert(!qu->children.head && !qu->children.tail); + assert(qu->retries <= ads->nservers + 1); + checkc_query(ads, qu); checkc_query_alloc(ads, qu);}); +} + +static void checkc_queue_childw(adns_state ads) +{ + adns_query parent, child; + + DLIST_CHECK(ads->childw, parent,, { + assert(parent->state == query_childw); + assert(parent->children.head); + DLIST_CHECK(parent->children, child, siblings., { + assert(child->parent == parent); + assert(child->state != query_done);}); + checkc_query(ads, parent); + checkc_query_alloc(ads, parent);}); +} + +static void checkc_queue_output(adns_state ads) +{ + adns_query qu; + + DLIST_CHECK(ads->output, qu,, { + assert(qu->state == query_done); + assert(!qu->children.head && !qu->children.tail); + assert(!qu->parent); + assert(!qu->allocations.head && !qu->allocations.tail); + checkc_query(ads, qu);}); +} + +void adns__consistency(adns_state ads, adns_query qu, + consistency_checks cc) +{ + adns_query search; + + switch (cc) { + case cc_user: + break; + case cc_entex: + if (!(ads->iflags & adns_if_checkc_entex)) + return; + break; + case cc_freq: + if ((ads->iflags & adns_if_checkc_freq) != + adns_if_checkc_freq) + return; + break; + default: + abort(); + } + + checkc_global(ads); + checkc_queue_udpw(ads); + checkc_queue_tcpw(ads); + checkc_queue_childw(ads); + checkc_queue_output(ads); + + if (qu) { + switch (qu->state) { + case query_tosend: + DLIST_ASSERTON(qu, search, ads->udpw,); + break; + case query_tcpw: + DLIST_ASSERTON(qu, search, ads->tcpw,); + break; + case query_childw: + DLIST_ASSERTON(qu, search, ads->childw,); + break; + case query_done: + DLIST_ASSERTON(qu, search, ads->output,); + break; + default: + assert(!"specific query state"); + } + } +} diff --git a/adns/config.h b/adns/config.h new file mode 100644 index 0000000..40aeffc --- /dev/null +++ b/adns/config.h @@ -0,0 +1,106 @@ +/* adns/config.h. Generated by configure. */ +/* src/config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if inline functions a la GCC are available. */ +#define HAVE_INLINE 1 + +/* Define if function attributes a la GCC 2.5 and higher are available. */ +#define HAVE_GNUC25_ATTRIB 1 + +/* Define if constant functions a la GCC 2.5 and higher are available. */ +#define HAVE_GNUC25_CONST 1 + +/* Define if nonreturning functions a la GCC 2.5 and higher are available. */ +#define HAVE_GNUC25_NORETURN 1 + +/* Define if printf-format argument lists a la GCC are available. */ +#define HAVE_GNUC25_PRINTFFORMAT 1 + +/* Define if we want to include rpc/types.h. Crap BSDs put INADDR_LOOPBACK there. */ +/* #undef HAVEUSE_RPCTYPES_H */ + +/* Define if you have the poll function. */ +/* #undef HAVE_POLL */ + +/* Define if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the nsl library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define if you have the socket library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Use the definitions: */ + +#ifndef HAVE_INLINE +#define inline +#endif + +#ifdef HAVE_POLL +#include +#else +/* kludge it up */ +struct pollfd { int fd; short events; short revents; }; +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#endif + +/* GNU C attributes. */ +#ifndef FUNCATTR +#ifdef HAVE_GNUC25_ATTRIB +#define FUNCATTR(x) __attribute__(x) +#else +#define FUNCATTR(x) +#endif +#endif + +/* GNU C printf formats, or null. */ +#ifndef ATTRPRINTF +#ifdef HAVE_GNUC25_PRINTFFORMAT +#define ATTRPRINTF(si,tc) format(printf,si,tc) +#else +#define ATTRPRINTF(si,tc) +#endif +#endif +#ifndef PRINTFFORMAT +#define PRINTFFORMAT(si,tc) FUNCATTR((ATTRPRINTF(si,tc))) +#endif + +/* GNU C nonreturning functions, or null. */ +#ifndef ATTRNORETURN +#ifdef HAVE_GNUC25_NORETURN +#define ATTRNORETURN noreturn +#else +#define ATTRNORETURN +#endif +#endif +#ifndef NONRETURNING +#define NONRETURNING FUNCATTR((ATTRNORETURN)) +#endif + +/* Combination of both the above. */ +#ifndef NONRETURNPRINTFFORMAT +#define NONRETURNPRINTFFORMAT(si,tc) FUNCATTR((ATTRPRINTF(si,tc),ATTRNORETURN)) +#endif + +/* GNU C constant functions, or null. */ +#ifndef ATTRCONST +#ifdef HAVE_GNUC25_CONST +#define ATTRCONST const +#else +#define ATTRCONST +#endif +#endif +#ifndef CONSTANT +#define CONSTANT FUNCATTR((ATTRCONST)) +#endif + +#ifdef HAVEUSE_RPCTYPES_H +#include +#endif + +#ifdef HAVE_SYS_SELECT_H +#include +#endif diff --git a/adns/config.h.in b/adns/config.h.in new file mode 100644 index 0000000..a22abe8 --- /dev/null +++ b/adns/config.h.in @@ -0,0 +1,105 @@ +/* src/config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if inline functions a la GCC are available. */ +#undef HAVE_INLINE + +/* Define if function attributes a la GCC 2.5 and higher are available. */ +#undef HAVE_GNUC25_ATTRIB + +/* Define if constant functions a la GCC 2.5 and higher are available. */ +#undef HAVE_GNUC25_CONST + +/* Define if nonreturning functions a la GCC 2.5 and higher are available. */ +#undef HAVE_GNUC25_NORETURN + +/* Define if printf-format argument lists a la GCC are available. */ +#undef HAVE_GNUC25_PRINTFFORMAT + +/* Define if we want to include rpc/types.h. Crap BSDs put INADDR_LOOPBACK there. */ +#undef HAVEUSE_RPCTYPES_H + +/* Define if you have the poll function. */ +#undef HAVE_POLL + +/* Define if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define if you have the nsl library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define if you have the socket library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Use the definitions: */ + +#ifndef HAVE_INLINE +#define inline +#endif + +#ifdef HAVE_POLL +#include +#else +/* kludge it up */ +struct pollfd { int fd; short events; short revents; }; +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#endif + +/* GNU C attributes. */ +#ifndef FUNCATTR +#ifdef HAVE_GNUC25_ATTRIB +#define FUNCATTR(x) __attribute__(x) +#else +#define FUNCATTR(x) +#endif +#endif + +/* GNU C printf formats, or null. */ +#ifndef ATTRPRINTF +#ifdef HAVE_GNUC25_PRINTFFORMAT +#define ATTRPRINTF(si,tc) format(printf,si,tc) +#else +#define ATTRPRINTF(si,tc) +#endif +#endif +#ifndef PRINTFFORMAT +#define PRINTFFORMAT(si,tc) FUNCATTR((ATTRPRINTF(si,tc))) +#endif + +/* GNU C nonreturning functions, or null. */ +#ifndef ATTRNORETURN +#ifdef HAVE_GNUC25_NORETURN +#define ATTRNORETURN noreturn +#else +#define ATTRNORETURN +#endif +#endif +#ifndef NONRETURNING +#define NONRETURNING FUNCATTR((ATTRNORETURN)) +#endif + +/* Combination of both the above. */ +#ifndef NONRETURNPRINTFFORMAT +#define NONRETURNPRINTFFORMAT(si,tc) FUNCATTR((ATTRPRINTF(si,tc),ATTRNORETURN)) +#endif + +/* GNU C constant functions, or null. */ +#ifndef ATTRCONST +#ifdef HAVE_GNUC25_CONST +#define ATTRCONST const +#else +#define ATTRCONST +#endif +#endif +#ifndef CONSTANT +#define CONSTANT FUNCATTR((ATTRCONST)) +#endif + +#ifdef HAVEUSE_RPCTYPES_H +#include +#endif + +#ifdef HAVE_SYS_SELECT_H +#include +#endif diff --git a/adns/dlist.h b/adns/dlist.h new file mode 100644 index 0000000..ebc3ff9 --- /dev/null +++ b/adns/dlist.h @@ -0,0 +1,75 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * dlist.h + * - macros for handling doubly linked lists + */ +/* + * This file is + * Copyright (C) 1997-1999 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef ADNS_DLIST_H_INCLUDED +#define ADNS_DLIST_H_INCLUDED + +#define ALIST_INIT(list) ((list).head= (list).tail= 0) +#define ALINK_INIT(link) ((link).next= (link).back= 0) + +#define LIST_UNLINK_PART(list,node,part) \ + do { \ + if ((node)->part back) (node)->part back->part next= (node)->part next; \ + else (list).head= (node)->part next; \ + if ((node)->part next) (node)->part next->part back= (node)->part back; \ + else (list).tail= (node)->part back; \ + } while(0) + +#define LIST_LINK_TAIL_PART(list,node,part) \ + do { \ + (node)->part next= 0; \ + (node)->part back= (list).tail; \ + if ((list).tail) (list).tail->part next= (node); else (list).head= (node); \ + (list).tail= (node); \ + } while(0) + +#define LIST_UNLINK(list,node) LIST_UNLINK_PART(list,node,) +#define LIST_LINK_TAIL(list,node) LIST_LINK_TAIL_PART(list,node,) + +#endif diff --git a/adns/event.c b/adns/event.c new file mode 100644 index 0000000..cf4332c --- /dev/null +++ b/adns/event.c @@ -0,0 +1,938 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * event.c + * - event loop core + * - TCP connection management + * - user-visible check/wait and event-loop-related functions + */ +/* + * This file is + * Copyright (C) 1997-2000 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "tvarith.h" + +/* TCP connection management. */ + +static void tcp_close(adns_state ads) +{ + int serv; + + serv = ads->tcpserver; + close(ads->tcpsocket); + ads->tcpsocket = -1; + ads->tcprecv.used = ads->tcprecv_skip = ads->tcpsend.used = 0; +} + +void adns__tcp_broken(adns_state ads, const char *what, const char *why) +{ + int serv; + adns_query qu; + + assert(ads->tcpstate == server_connecting + || ads->tcpstate == server_ok); + serv = ads->tcpserver; + if (what) + adns__warn(ads, serv, 0, "TCP connection failed: %s: %s", + what, why); + + if (ads->tcpstate == server_connecting) { + /* Counts as a retry for all the queries waiting for TCP. */ + for (qu = ads->tcpw.head; qu; qu = qu->next) + qu->retries++; + } + + tcp_close(ads); + ads->tcpstate = server_broken; + ads->tcpserver = (serv + 1) % ads->nservers; +} + +static void tcp_connected(adns_state ads, struct timeval now) +{ + adns_query qu, nqu; + + adns__debug(ads, ads->tcpserver, 0, "TCP connected"); + ads->tcpstate = server_ok; + for (qu = ads->tcpw.head; qu && ads->tcpstate == server_ok; + qu = nqu) { + nqu = qu->next; + assert(qu->state == query_tcpw); + adns__querysend_tcp(qu, now); + } +} + +void adns__tcp_tryconnect(adns_state ads, struct timeval now) +{ + int r, fd, tries; + struct sockaddr_in addr; + struct protoent *proto; + + for (tries = 0; tries < ads->nservers; tries++) { + switch (ads->tcpstate) { + case server_connecting: + case server_ok: + case server_broken: + return; + case server_disconnected: + break; + default: + abort(); + } + + assert(!ads->tcpsend.used); + assert(!ads->tcprecv.used); + assert(!ads->tcprecv_skip); + + proto = getprotobyname("tcp"); + if (!proto) { + adns__diag(ads, -1, 0, + "unable to find protocol no. for TCP !"); + return; + } + fd = socket(AF_INET, SOCK_STREAM, proto->p_proto); + if (fd < 0) { + adns__diag(ads, -1, 0, + "cannot create TCP socket: %s", + strerror(errno)); + return; + } + r = adns__setnonblock(ads, fd); + if (r) { + adns__diag(ads, -1, 0, + "cannot make TCP socket nonblocking: %s", + strerror(r)); + close(fd); + return; + } + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(DNS_PORT); + addr.sin_addr = ads->servers[ads->tcpserver].addr; + r = connect(fd, (const struct sockaddr *) &addr, + sizeof(addr)); + ads->tcpsocket = fd; + ads->tcpstate = server_connecting; + if (r == 0) { + tcp_connected(ads, now); + return; + } + if (errno == EWOULDBLOCK || errno == EINPROGRESS) { + ads->tcptimeout = now; + timevaladd(&ads->tcptimeout, TCPCONNMS); + return; + } + adns__tcp_broken(ads, "connect", strerror(errno)); + ads->tcpstate = server_disconnected; + } +} + +/* Timeout handling functions. */ + +void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io, + struct timeval *tv_buf) +{ + const struct timeval *now; + int r; + + now = *now_io; + if (now) + return; + r = gettimeofday(tv_buf, 0); + if (!r) { + *now_io = tv_buf; + return; + } + adns__diag(ads, -1, 0, "gettimeofday failed: %s", strerror(errno)); + adns_globalsystemfailure(ads); + return; +} + +static void inter_immed(struct timeval **tv_io, struct timeval *tvbuf) +{ + struct timeval *rbuf; + + if (!tv_io) + return; + + rbuf = *tv_io; + if (!rbuf) { + *tv_io = rbuf = tvbuf; + } + + timerclear(rbuf); +} + +static void inter_maxto(struct timeval **tv_io, struct timeval *tvbuf, + struct timeval maxto) +{ + struct timeval *rbuf; + + if (!tv_io) + return; + rbuf = *tv_io; + if (!rbuf) { + *tvbuf = maxto; + *tv_io = tvbuf; + } else { + if (timercmp(rbuf, &maxto, >)) + *rbuf = maxto; + } +/*fprintf(stderr,"inter_maxto maxto=%ld.%06ld result=%ld.%06ld\n", + maxto.tv_sec,maxto.tv_usec,(**tv_io).tv_sec,(**tv_io).tv_usec);*/ +} + +static void inter_maxtoabs(struct timeval **tv_io, struct timeval *tvbuf, + struct timeval now, struct timeval maxtime) +{ + /* tv_io may be 0 */ + ldiv_t dr; + +/*fprintf(stderr,"inter_maxtoabs now=%ld.%06ld maxtime=%ld.%06ld\n", + now.tv_sec,now.tv_usec,maxtime.tv_sec,maxtime.tv_usec);*/ + if (!tv_io) + return; + maxtime.tv_sec -= (now.tv_sec + 2); + maxtime.tv_usec -= (now.tv_usec - 2000000); + dr = ldiv(maxtime.tv_usec, 1000000); + maxtime.tv_sec += dr.quot; + maxtime.tv_usec -= dr.quot * 1000000; + if (maxtime.tv_sec < 0) + timerclear(&maxtime); + inter_maxto(tv_io, tvbuf, maxtime); +} + +static void timeouts_queue(adns_state ads, int act, + struct timeval **tv_io, struct timeval *tvbuf, + struct timeval now, struct query_queue *queue) +{ + adns_query qu, nqu; + + for (qu = queue->head; qu; qu = nqu) { + nqu = qu->next; + if (!timercmp(&now, &qu->timeout, >)) { + inter_maxtoabs(tv_io, tvbuf, now, qu->timeout); + } else { + if (!act) { + inter_immed(tv_io, tvbuf); + return; + } + LIST_UNLINK(*queue, qu); + if (qu->state != query_tosend) { + adns__query_fail(qu, adns_s_timeout); + } else { + adns__query_send(qu, now); + } + nqu = queue->head; + } + } +} + +static void tcp_events(adns_state ads, int act, + struct timeval **tv_io, struct timeval *tvbuf, + struct timeval now) +{ + adns_query qu, nqu; + + for (;;) { + switch (ads->tcpstate) { + case server_broken: + if (!act) { + inter_immed(tv_io, tvbuf); + return; + } + for (qu = ads->tcpw.head; qu; qu = nqu) { + nqu = qu->next; + assert(qu->state == query_tcpw); + if (qu->retries > ads->nservers) { + LIST_UNLINK(ads->tcpw, qu); + adns__query_fail(qu, + adns_s_allservfail); + } + } + ads->tcpstate = server_disconnected; + case server_disconnected: /* fall through */ + if (!ads->tcpw.head) + return; + if (!act) { + inter_immed(tv_io, tvbuf); + return; + } + adns__tcp_tryconnect(ads, now); + break; + case server_ok: + if (ads->tcpw.head) + return; + if (!ads->tcptimeout.tv_sec) { + assert(!ads->tcptimeout.tv_usec); + ads->tcptimeout = now; + timevaladd(&ads->tcptimeout, TCPIDLEMS); + } + case server_connecting: /* fall through */ + if (!act || !timercmp(&now, &ads->tcptimeout, >)) { + inter_maxtoabs(tv_io, tvbuf, now, + ads->tcptimeout); + return; + } + { + /* TCP timeout has happened */ + switch (ads->tcpstate) { + case server_connecting: /* failed to connect */ + adns__tcp_broken(ads, + "unable to make connection", + "timed out"); + break; + case server_ok: /* idle timeout */ + tcp_close(ads); + ads->tcpstate = + server_disconnected; + return; + default: + abort(); + } + } + break; + default: + abort(); + } + } + return; +} + +void adns__timeouts(adns_state ads, int act, + struct timeval **tv_io, struct timeval *tvbuf, + struct timeval now) +{ + timeouts_queue(ads, act, tv_io, tvbuf, now, &ads->udpw); + timeouts_queue(ads, act, tv_io, tvbuf, now, &ads->tcpw); + tcp_events(ads, act, tv_io, tvbuf, now); +} + +void adns_firsttimeout(adns_state ads, + struct timeval **tv_io, struct timeval *tvbuf, + struct timeval now) +{ + adns__consistency(ads, 0, cc_entex); + adns__timeouts(ads, 0, tv_io, tvbuf, now); + adns__consistency(ads, 0, cc_entex); +} + +void adns_processtimeouts(adns_state ads, const struct timeval *now) +{ + struct timeval tv_buf; + + adns__consistency(ads, 0, cc_entex); + adns__must_gettimeofday(ads, &now, &tv_buf); + if (now) + adns__timeouts(ads, 1, 0, 0, *now); + adns__consistency(ads, 0, cc_entex); +} + +/* fd handling functions. These are the top-level of the real work of + * reception and often transmission. + */ + +int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]) +{ + /* Returns the number of entries filled in. Always zeroes revents. */ + + assert(MAX_POLLFDS == 2); + + pollfds_buf[0].fd = ads->udpsocket; + pollfds_buf[0].events = POLLIN; + pollfds_buf[0].revents = 0; + + switch (ads->tcpstate) { + case server_disconnected: + case server_broken: + return 1; + case server_connecting: + pollfds_buf[1].events = POLLOUT; + break; + case server_ok: + pollfds_buf[1].events = + ads->tcpsend. + used ? POLLIN | POLLOUT | POLLPRI : POLLIN | POLLPRI; + break; + default: + abort(); + } + pollfds_buf[1].fd = ads->tcpsocket; + return 2; +} + +int adns_processreadable(adns_state ads, int fd, const struct timeval *now) +{ + int want, dgramlen, r, udpaddrlen, serv, old_skip; + byte udpbuf[DNS_MAXUDP]; + struct sockaddr_in udpaddr; + + adns__consistency(ads, 0, cc_entex); + + switch (ads->tcpstate) { + case server_disconnected: + case server_broken: + case server_connecting: + break; + case server_ok: + if (fd != ads->tcpsocket) + break; + assert(!ads->tcprecv_skip); + do { + if (ads->tcprecv.used >= ads->tcprecv_skip + 2) { + dgramlen = + ((ads->tcprecv. + buf[ads->tcprecv_skip] << 8) | ads-> + tcprecv.buf[ads->tcprecv_skip + 1]); + if (ads->tcprecv.used >= + ads->tcprecv_skip + 2 + dgramlen) { + old_skip = ads->tcprecv_skip; + ads->tcprecv_skip += 2 + dgramlen; + adns__procdgram(ads, + ads->tcprecv.buf + + old_skip + 2, + dgramlen, + ads->tcpserver, 1, + *now); + continue; + } else { + want = 2 + dgramlen; + } + } else { + want = 2; + } + ads->tcprecv.used -= ads->tcprecv_skip; + memmove(ads->tcprecv.buf, + ads->tcprecv.buf + ads->tcprecv_skip, + ads->tcprecv.used); + ads->tcprecv_skip = 0; + if (!adns__vbuf_ensure(&ads->tcprecv, want)) { + r = ENOMEM; + goto xit; + } + assert(ads->tcprecv.used <= ads->tcprecv.avail); + if (ads->tcprecv.used == ads->tcprecv.avail) + continue; + r = read(ads->tcpsocket, + ads->tcprecv.buf + ads->tcprecv.used, + ads->tcprecv.avail - ads->tcprecv.used); + if (r > 0) { + ads->tcprecv.used += r; + } else { + if (r) { + if (errno == EAGAIN + || errno == EWOULDBLOCK) { + r = 0; + goto xit; + } + if (errno == EINTR) + continue; + if (errno_resources(errno)) { + r = errno; + goto xit; + } + } + adns__tcp_broken(ads, "read", + r ? strerror(errno) : + "closed"); + } + } while (ads->tcpstate == server_ok); + r = 0; + goto xit; + default: + abort(); + } + if (fd == ads->udpsocket) { + for (;;) { + udpaddrlen = sizeof(udpaddr); + r = recvfrom(ads->udpsocket, udpbuf, + sizeof(udpbuf), 0, + (struct sockaddr *) &udpaddr, + &udpaddrlen); + if (r < 0) { + if (errno == EAGAIN + || errno == EWOULDBLOCK) { + r = 0; + goto xit; + } + if (errno == EINTR) + continue; + if (errno_resources(errno)) { + r = errno; + goto xit; + } + adns__warn(ads, -1, 0, + "datagram receive error: %s", + strerror(errno)); + r = 0; + goto xit; + } + if (udpaddrlen != sizeof(udpaddr)) { + adns__diag(ads, -1, 0, + "datagram received with wrong address length %d" + " (expected %lu)", udpaddrlen, + (unsigned long) + sizeof(udpaddr)); + continue; + } + if (udpaddr.sin_family != AF_INET) { + adns__diag(ads, -1, 0, + "datagram received with wrong protocol family" + " %u (expected %u)", + udpaddr.sin_family, AF_INET); + continue; + } + if (ntohs(udpaddr.sin_port) != DNS_PORT) { + adns__diag(ads, -1, 0, + "datagram received from wrong port %u (expected %u)", + ntohs(udpaddr.sin_port), + DNS_PORT); + continue; + } + for (serv = 0; + serv < ads->nservers && + ads->servers[serv].addr.s_addr != + udpaddr.sin_addr.s_addr; serv++); + if (serv >= ads->nservers) { + adns__warn(ads, -1, 0, + "datagram received from unknown nameserver %s", + inet_ntoa(udpaddr.sin_addr)); + continue; + } + adns__procdgram(ads, udpbuf, r, serv, 0, *now); + } + } + r = 0; + xit: + adns__consistency(ads, 0, cc_entex); + return r; +} + +int adns_processwriteable(adns_state ads, int fd, + const struct timeval *now) +{ + int r; + + adns__consistency(ads, 0, cc_entex); + + switch (ads->tcpstate) { + case server_disconnected: + case server_broken: + break; + case server_connecting: + if (fd != ads->tcpsocket) + break; + assert(ads->tcprecv.used == 0); + assert(ads->tcprecv_skip == 0); + for (;;) { + if (!adns__vbuf_ensure(&ads->tcprecv, 1)) { + r = ENOMEM; + goto xit; + } + r = read(ads->tcpsocket, &ads->tcprecv.buf, 1); + if (r == 0 + || (r < 0 + && (errno == EAGAIN + || errno == EWOULDBLOCK))) { + tcp_connected(ads, *now); + r = 0; + goto xit; + } + if (r > 0) { + adns__tcp_broken(ads, "connect/read", + "sent data before first request"); + r = 0; + goto xit; + } + if (errno == EINTR) + continue; + if (errno_resources(errno)) { + r = errno; + goto xit; + } + adns__tcp_broken(ads, "connect/read", + strerror(errno)); + r = 0; + goto xit; + } /* not reached */ + case server_ok: + if (fd != ads->tcpsocket) + break; + while (ads->tcpsend.used) { + adns__sigpipe_protect(ads); + r = write(ads->tcpsocket, ads->tcpsend.buf, + ads->tcpsend.used); + adns__sigpipe_unprotect(ads); + if (r < 0) { + if (errno == EINTR) + continue; + if (errno == EAGAIN + || errno == EWOULDBLOCK) { + r = 0; + goto xit; + } + if (errno_resources(errno)) { + r = errno; + goto xit; + } + adns__tcp_broken(ads, "write", + strerror(errno)); + r = 0; + goto xit; + } else if (r > 0) { + ads->tcpsend.used -= r; + memmove(ads->tcpsend.buf, + ads->tcpsend.buf + r, + ads->tcpsend.used); + } + } + r = 0; + goto xit; + default: + abort(); + } + r = 0; + xit: + adns__consistency(ads, 0, cc_entex); + return r; +} + +int adns_processexceptional(adns_state ads, int fd, + const struct timeval *now) +{ + adns__consistency(ads, 0, cc_entex); + switch (ads->tcpstate) { + case server_disconnected: + case server_broken: + break; + case server_connecting: + case server_ok: + if (fd != ads->tcpsocket) + break; + adns__tcp_broken(ads, "poll/select", + "exceptional condition detected"); + break; + default: + abort(); + } + adns__consistency(ads, 0, cc_entex); + return 0; +} + +static void fd_event(adns_state ads, int fd, + int revent, int pollflag, + int maxfd, const fd_set * fds, + int (*func) (adns_state, int fd, + const struct timeval * now), + struct timeval now, int *r_r) +{ + int r; + + if (!(revent & pollflag)) + return; + if (fds && !(fd < maxfd && FD_ISSET(fd, fds))) + return; + r = func(ads, fd, &now); + if (r) { + if (r_r) { + *r_r = r; + } else { + adns__diag(ads, -1, 0, + "process fd failed after select: %s", + strerror(errno)); + adns_globalsystemfailure(ads); + } + } +} + +void adns__fdevents(adns_state ads, + const struct pollfd *pollfds, int npollfds, + int maxfd, const fd_set * readfds, + const fd_set * writefds, const fd_set * exceptfds, + struct timeval now, int *r_r) +{ + int i, fd, revents; + + for (i = 0; i < npollfds; i++) { + fd = pollfds[i].fd; + if (fd >= maxfd) + maxfd = fd + 1; + revents = pollfds[i].revents; + fd_event(ads, fd, revents, POLLIN, maxfd, readfds, + adns_processreadable, now, r_r); + fd_event(ads, fd, revents, POLLOUT, maxfd, writefds, + adns_processwriteable, now, r_r); + fd_event(ads, fd, revents, POLLPRI, maxfd, exceptfds, + adns_processexceptional, now, r_r); + } +} + +/* Wrappers for select(2). */ + +void adns_beforeselect(adns_state ads, int *maxfd_io, fd_set * readfds_io, + fd_set * writefds_io, fd_set * exceptfds_io, + struct timeval **tv_mod, struct timeval *tv_tobuf, + const struct timeval *now) +{ + struct timeval tv_nowbuf; + struct pollfd pollfds[MAX_POLLFDS]; + int i, fd, maxfd, npollfds; + + adns__consistency(ads, 0, cc_entex); + + if (tv_mod + && (!*tv_mod || (*tv_mod)->tv_sec || (*tv_mod)->tv_usec)) { + /* The caller is planning to sleep. */ + adns__must_gettimeofday(ads, &now, &tv_nowbuf); + if (!now) { + inter_immed(tv_mod, tv_tobuf); + adns__consistency(ads, 0, cc_entex); + return; +#if 0 + goto xit; +#endif + } + adns__timeouts(ads, 0, tv_mod, tv_tobuf, *now); + } + + npollfds = adns__pollfds(ads, pollfds); + maxfd = *maxfd_io; + for (i = 0; i < npollfds; i++) { + fd = pollfds[i].fd; + if (fd >= maxfd) + maxfd = fd + 1; + if (pollfds[i].events & POLLIN) + FD_SET(fd, readfds_io); + if (pollfds[i].events & POLLOUT) + FD_SET(fd, writefds_io); + if (pollfds[i].events & POLLPRI) + FD_SET(fd, exceptfds_io); + } + *maxfd_io = maxfd; +#if 0 + xit: +#endif + adns__consistency(ads, 0, cc_entex); +} + +void adns_afterselect(adns_state ads, int maxfd, const fd_set * readfds, + const fd_set * writefds, const fd_set * exceptfds, + const struct timeval *now) +{ + struct timeval tv_buf; + struct pollfd pollfds[MAX_POLLFDS]; + int npollfds, i; + + adns__consistency(ads, 0, cc_entex); + adns__must_gettimeofday(ads, &now, &tv_buf); + if (!now) + goto xit; + adns_processtimeouts(ads, now); + + npollfds = adns__pollfds(ads, pollfds); + for (i = 0; i < npollfds; i++) + pollfds[i].revents = POLLIN | POLLOUT | POLLPRI; + adns__fdevents(ads, + pollfds, npollfds, + maxfd, readfds, writefds, exceptfds, *now, 0); + xit: + adns__consistency(ads, 0, cc_entex); +} + +/* General helpful functions. */ + +void adns_globalsystemfailure(adns_state ads) +{ + adns__consistency(ads, 0, cc_entex); + + while (ads->udpw.head) + adns__query_fail(ads->udpw.head, adns_s_systemfail); + while (ads->tcpw.head) + adns__query_fail(ads->tcpw.head, adns_s_systemfail); + + switch (ads->tcpstate) { + case server_connecting: + case server_ok: + adns__tcp_broken(ads, 0, 0); + break; + case server_disconnected: + case server_broken: + break; + default: + abort(); + } + adns__consistency(ads, 0, cc_entex); +} + +int adns_processany(adns_state ads) +{ + int r, i; + struct timeval now; + struct pollfd pollfds[MAX_POLLFDS]; + int npollfds; + + adns__consistency(ads, 0, cc_entex); + + r = gettimeofday(&now, 0); + if (!r) + adns_processtimeouts(ads, &now); + + /* We just use adns__fdevents to loop over the fd's trying them. + * This seems more sensible than calling select, since we're most + * likely just to want to do a read on one or two fds anyway. + */ + npollfds = adns__pollfds(ads, pollfds); + for (i = 0; i < npollfds; i++) + pollfds[i].revents = pollfds[i].events & ~POLLPRI; + adns__fdevents(ads, pollfds, npollfds, 0, 0, 0, 0, now, &r); + + adns__consistency(ads, 0, cc_entex); + return 0; +} + +void adns__autosys(adns_state ads, struct timeval now) +{ + if (ads->iflags & adns_if_noautosys) + return; + adns_processany(ads); +} + +int adns__internal_check(adns_state ads, + adns_query * query_io, + adns_answer ** answer, void **context_r) +{ + adns_query qu; + + qu = *query_io; + if (!qu) { + if (ads->output.head) { + qu = ads->output.head; + } else if (ads->udpw.head || ads->tcpw.head) { + return EAGAIN; + } else { + return ESRCH; + } + } else { + if (qu->id >= 0) + return EAGAIN; + } + LIST_UNLINK(ads->output, qu); + *answer = qu->answer; + if (context_r) + *context_r = qu->ctx.ext; + *query_io = qu; + free(qu); + return 0; +} + +int adns_wait(adns_state ads, + adns_query * query_io, + adns_answer ** answer_r, void **context_r) +{ + int r, maxfd, rsel; + fd_set readfds, writefds, exceptfds; + struct timeval tvbuf, *tvp; + + adns__consistency(ads, *query_io, cc_entex); + for (;;) { + r = adns__internal_check(ads, query_io, answer_r, + context_r); + if (r != EAGAIN) + break; + maxfd = 0; + tvp = 0; + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + adns_beforeselect(ads, &maxfd, &readfds, &writefds, + &exceptfds, &tvp, &tvbuf, 0); + assert(tvp); + rsel = select(maxfd, &readfds, &writefds, &exceptfds, tvp); + if (rsel == -1) { + if (errno == EINTR) { + if (ads->iflags & adns_if_eintr) { + r = EINTR; + break; + } + } else { + adns__diag(ads, -1, 0, + "select failed in wait: %s", + strerror(errno)); + adns_globalsystemfailure(ads); + } + } else { + assert(rsel >= 0); + adns_afterselect(ads, maxfd, &readfds, &writefds, + &exceptfds, 0); + } + } + adns__consistency(ads, 0, cc_entex); + return r; +} + +int adns_check(adns_state ads, + adns_query * query_io, + adns_answer ** answer_r, void **context_r) +{ + struct timeval now; + int r; + + adns__consistency(ads, *query_io, cc_entex); + r = gettimeofday(&now, 0); + if (!r) + adns__autosys(ads, now); + + r = adns__internal_check(ads, query_io, answer_r, context_r); + adns__consistency(ads, 0, cc_entex); + return r; +} diff --git a/adns/general.c b/adns/general.c new file mode 100644 index 0000000..5159ce8 --- /dev/null +++ b/adns/general.c @@ -0,0 +1,445 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * general.c + * - diagnostic functions + * - vbuf handling + */ +/* + * This file is + * Copyright (C) 1997-2000 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include +#include +#include +#include + +#include "internal.h" + +/* Core diagnostic functions */ + +void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, + int serv, adns_query qu, const char *fmt, va_list al) +{ + const char *bef, *aft; + vbuf vb; + + if (!ads->diagfile || + (!(ads->iflags & adns_if_debug) + && (!prevent || (ads->iflags & prevent)))) + return; + + if (ads->iflags & adns_if_logpid) { + fprintf(ads->diagfile, "adns%s [%ld]: ", pfx, + (long) getpid()); + } else { + fprintf(ads->diagfile, "adns%s: ", pfx); + } + + vfprintf(ads->diagfile, fmt, al); + + bef = " ("; + aft = "\n"; + + if (qu && qu->query_dgram) { + adns__vbuf_init(&vb); + fprintf(ads->diagfile, "%sQNAME=%s, QTYPE=%s", + bef, + adns__diag_domain(qu->ads, -1, 0, &vb, + qu->query_dgram, qu->query_dglen, + DNS_HDRSIZE), + qu->typei ? qu->typei->rrtname : ""); + if (qu->typei && qu->typei->fmtname) + fprintf(ads->diagfile, "(%s)", qu->typei->fmtname); + bef = ", "; + aft = ")\n"; + adns__vbuf_free(&vb); + } + + if (serv >= 0) { + fprintf(ads->diagfile, "%sNS=%s", bef, + inet_ntoa(ads->servers[serv].addr)); + bef = ", "; + aft = ")\n"; + } + + fputs(aft, ads->diagfile); +} + +void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, + ...) +{ + va_list al; + + va_start(al, fmt); + adns__vdiag(ads, " debug", 0, serv, qu, fmt, al); + va_end(al); +} + +void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, + ...) +{ + va_list al; + + va_start(al, fmt); + adns__vdiag(ads, " warning", + adns_if_noerrprint | adns_if_noserverwarn, serv, qu, + fmt, al); + va_end(al); +} + +void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, + ...) +{ + va_list al; + + va_start(al, fmt); + adns__vdiag(ads, "", adns_if_noerrprint, serv, qu, fmt, al); + va_end(al); +} + +/* vbuf functions */ + +void adns__vbuf_init(vbuf * vb) +{ + vb->used = vb->avail = 0; + vb->buf = 0; +} + +int adns__vbuf_ensure(vbuf * vb, int want) +{ + void *nb; + + if (vb->avail >= want) + return 1; + nb = realloc(vb->buf, want); + if (!nb) + return 0; + vb->buf = nb; + vb->avail = want; + return 1; +} + +void adns__vbuf_appendq(vbuf * vb, const byte * data, int len) +{ + memcpy(vb->buf + vb->used, data, len); + vb->used += len; +} + +int adns__vbuf_append(vbuf * vb, const byte * data, int len) +{ + int newlen; + void *nb; + + newlen = vb->used + len; + if (vb->avail < newlen) { + if (newlen < 20) + newlen = 20; + newlen <<= 1; + nb = realloc(vb->buf, newlen); + if (!nb) { + newlen = vb->used + len; + nb = realloc(vb->buf, newlen); + } + if (!nb) + return 0; + vb->buf = nb; + vb->avail = newlen; + } + adns__vbuf_appendq(vb, data, len); + return 1; +} + +int adns__vbuf_appendstr(vbuf * vb, const char *data) +{ + int l; + l = strlen(data); + return adns__vbuf_append(vb, data, l); +} + +void adns__vbuf_free(vbuf * vb) +{ + free(vb->buf); + adns__vbuf_init(vb); +} + +/* Additional diagnostic functions */ + +const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, + vbuf * vb, const byte * dgram, int dglen, + int cbyte) +{ + adns_status st; + + st = adns__parse_domain(ads, serv, qu, vb, pdf_quoteok, dgram, + dglen, &cbyte, dglen); + if (st == adns_s_nomemory) { + return ""; + } + if (st) { + vb->used = 0; + if (!(adns__vbuf_appendstr(vb, "") && + adns__vbuf_append(vb, "", 1))) { + return + ""; + } + } + if (!vb->used) { + adns__vbuf_appendstr(vb, ""); + adns__vbuf_append(vb, "", 1); + } + return vb->buf; +} + +adns_status adns_rr_info(adns_rrtype type, + const char **rrtname_r, const char **fmtname_r, + int *len_r, const void *datap, char **data_r) +{ + const typeinfo *typei; + vbuf vb; + adns_status st; + + typei = adns__findtype(type); + if (!typei) + return adns_s_unknownrrtype; + + if (rrtname_r) + *rrtname_r = typei->rrtname; + if (fmtname_r) + *fmtname_r = typei->fmtname; + if (len_r) + *len_r = typei->rrsz; + + if (!datap) + return adns_s_ok; + + adns__vbuf_init(&vb); + st = typei->convstring(&vb, datap); + if (st) + goto x_freevb; + if (!adns__vbuf_append(&vb, "", 1)) { + st = adns_s_nomemory; + goto x_freevb; + } + assert(strlen(vb.buf) == vb.used - 1); + *data_r = realloc(vb.buf, vb.used); + if (!*data_r) + *data_r = vb.buf; + return adns_s_ok; + + x_freevb: + adns__vbuf_free(&vb); + return st; +} + + +#define SINFO(n,s) { adns_s_##n, #n, s } + +static const struct sinfo { + adns_status st; + const char *abbrev; + const char *string; +} sinfos[] = { + SINFO(ok, "OK"), + SINFO(nomemory, "Out of memory"), + SINFO(unknownrrtype, "Query not implemented in DNS library"), + SINFO(systemfail, "General resolver or system failure"), + SINFO(timeout, "DNS query timed out"), + SINFO(allservfail, "All nameservers failed"), + SINFO(norecurse, "Recursion denied by nameserver"), + SINFO(invalidresponse, "Nameserver sent bad response"), + SINFO(unknownformat, "Nameserver used unknown format"), + SINFO(rcodeservfail, "Nameserver reports failure"), + SINFO(rcodeformaterror, "Query not understood by nameserver"), + SINFO(rcodenotimplemented, + "Query not implemented by nameserver"), + SINFO(rcoderefused, "Query refused by nameserver"), + SINFO(rcodeunknown, "Nameserver sent unknown response code"), + SINFO(inconsistent, "Inconsistent resource records in DNS"), + SINFO(prohibitedcname, + "DNS alias found where canonical name wanted"), + SINFO(answerdomaininvalid, + "Found syntactically invalid domain name"), + SINFO(answerdomaintoolong, "Found overly-long domain name"), + SINFO(invaliddata, "Found invalid DNS data"), + SINFO(querydomainwrong, + "Domain invalid for particular DNS query type"), + SINFO(querydomaininvalid, + "Domain name is syntactically invalid"), + SINFO(querydomaintoolong, + "Domain name or component is too long"), SINFO(nxdomain, + "No such domain"), + SINFO(nodata, "No such data") +}; + +static int si_compar(const void *key, const void *elem) +{ + const adns_status *st = key; + const struct sinfo *si = elem; + + return *st < si->st ? -1 : *st > si->st ? 1 : 0; +} + +static const struct sinfo *findsinfo(adns_status st) +{ + return bsearch(&st, sinfos, sizeof(sinfos) / sizeof(*sinfos), + sizeof(*sinfos), si_compar); +} + +const char *adns_strerror(adns_status st) +{ + const struct sinfo *si; + + si = findsinfo(st); + return si->string; +} + +const char *adns_errabbrev(adns_status st) +{ + const struct sinfo *si; + + si = findsinfo(st); + return si->abbrev; +} + + +#define STINFO(max) { adns_s_max_##max, #max } + +static const struct stinfo { + adns_status stmax; + const char *abbrev; +} stinfos[] = { + { + adns_s_ok, "ok"}, + STINFO(localfail), + STINFO(remotefail), + STINFO(tempfail), + STINFO(misconfig), STINFO(misquery), STINFO(permfail) +}; + +static int sti_compar(const void *key, const void *elem) +{ + const adns_status *st = key; + const struct stinfo *sti = elem; + + adns_status here, min, max; + + here = *st; + min = (sti == stinfos) ? 0 : sti[-1].stmax + 1; + max = sti->stmax; + + return here < min ? -1 : here > max ? 1 : 0; +} + +const char *adns_errtypeabbrev(adns_status st) +{ + const struct stinfo *sti; + + sti = + bsearch(&st, stinfos, sizeof(stinfos) / sizeof(*stinfos), + sizeof(*stinfos), sti_compar); + return sti->abbrev; +} + + +void adns__isort(void *array, int nobjs, int sz, void *tempbuf, + int (*needswap) (void *context, const void *a, + const void *b), void *context) +{ + byte *data = array; + int i, place; + + for (i = 0; i < nobjs; i++) { + for (place = i; + place > 0 + && needswap(context, data + (place - 1) * sz, + data + i * sz); place--); + if (place != i) { + memcpy(tempbuf, data + i * sz, sz); + memmove(data + (place + 1) * sz, data + place * sz, + (i - place) * sz); + memcpy(data + place * sz, tempbuf, sz); + } + } +} + +/* SIGPIPE protection. */ + +void adns__sigpipe_protect(adns_state ads) +{ + sigset_t toblock; + struct sigaction sa; + int r; + + if (ads->iflags & adns_if_nosigpipe) + return; + + sigfillset(&toblock); + sigdelset(&toblock, SIGPIPE); + + sa.sa_handler = SIG_IGN; + sigfillset(&sa.sa_mask); + sa.sa_flags = 0; + + r = sigprocmask(SIG_SETMASK, &toblock, &ads->stdsigmask); + assert(!r); + r = sigaction(SIGPIPE, &sa, &ads->stdsigpipe); + assert(!r); +} + +void adns__sigpipe_unprotect(adns_state ads) +{ + int r; + + if (ads->iflags & adns_if_nosigpipe) + return; + + r = sigaction(SIGPIPE, &ads->stdsigpipe, 0); + assert(!r); + r = sigprocmask(SIG_SETMASK, &ads->stdsigmask, 0); + assert(!r); +} diff --git a/adns/internal.h b/adns/internal.h new file mode 100644 index 0000000..7a4740e --- /dev/null +++ b/adns/internal.h @@ -0,0 +1,770 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * internal.h + * - declarations of private objects with external linkage (adns__*) + * - definitons of internal macros + * - comments regarding library data structures + */ +/* + * This file is + * Copyright (C) 1997-2000 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef ADNS_INTERNAL_H_INCLUDED +#define ADNS_INTERNAL_H_INCLUDED + +#include "config.h" +typedef unsigned char byte; + +#include +#include +#include +#include +#include +#include + +#include + +#include "adns.h" +#include "dlist.h" + +#ifdef ADNS_REGRESS_TEST +# include "hredirect.h" +#endif + +/* Configuration and constants */ + +#define MAXSERVERS 5 +#define MAXSORTLIST 15 +#define UDPMAXRETRIES 15 +#define UDPRETRYMS 2000 +#define TCPWAITMS 30000 +#define TCPCONNMS 14000 +#define TCPIDLEMS 30000 +#define MAXTTLBELIEVE (7*86400) /* any TTL > 7 days is capped */ + +#define DNS_PORT 53 +#define DNS_MAXUDP 512 +#define DNS_MAXLABEL 63 +#define DNS_MAXDOMAIN 255 +#define DNS_HDRSIZE 12 +#define DNS_IDOFFSET 0 +#define DNS_CLASS_IN 1 + +#define DNS_INADDR_ARPA "in-addr", "arpa" + +#define MAX_POLLFDS ADNS_POLLFDS_RECOMMENDED + +typedef enum { + cc_user, + cc_entex, + cc_freq +} consistency_checks; + +typedef enum { + rcode_noerror, + rcode_formaterror, + rcode_servfail, + rcode_nxdomain, + rcode_notimp, + rcode_refused +} dns_rcode; + +/* Shared data structures */ + +typedef union { + adns_status status; + char *cp; + adns_rrtype type; + int i; + struct in_addr ia; + unsigned long ul; +} rr_align; + +typedef struct { + int used, avail; + byte *buf; +} vbuf; + +typedef struct { + adns_state ads; + adns_query qu; + int serv; + const byte *dgram; + int dglen, nsstart, nscount, arcount; + struct timeval now; +} parseinfo; + +typedef struct { + adns_rrtype type; + const char *rrtname; + const char *fmtname; + int rrsz; + + void (*makefinal) (adns_query qu, void *data); + /* Change memory management of *data. + * Previously, used alloc_interim, now use alloc_final. + */ + + adns_status(*convstring) (vbuf * vb, const void *data); + /* Converts the RR data to a string representation in vbuf. + * vbuf will be appended to (it must have been initialised), + * and will not be null-terminated by convstring. + */ + + adns_status(*parse) (const parseinfo * pai, int cbyte, int max, + void *store_r); + /* Parse one RR, in dgram of length dglen, starting at cbyte and + * extending until at most max. + * + * The RR should be stored at *store_r, of length qu->typei->rrsz. + * + * If there is an overrun which might indicate truncation, it should set + * *rdstart to -1; otherwise it may set it to anything else positive. + * + * nsstart is the offset of the authority section. + */ + + int (*diff_needswap) (adns_state ads, const void *datap_a, + const void *datap_b); + /* Returns !0 if RR a should be strictly after RR b in the sort order, + * 0 otherwise. Must not fail. + */ +} typeinfo; + +typedef struct allocnode { + struct allocnode *next, *back; +} allocnode; + +union maxalign { + byte d[1]; + struct in_addr ia; + long l; + void *p; + void (*fp) (void); + union maxalign *up; +} data; + +typedef struct { + void *ext; + void (*callback) (adns_query parent, adns_query child); + union { + adns_rr_addr ptr_parent_addr; + adns_rr_hostaddr *hostaddr; + } info; +} qcontext; + +struct adns__query { + adns_state ads; + enum { query_tosend, query_tcpw, query_childw, query_done } state; + adns_query back, next, parent; + struct { + adns_query head, tail; + } children; + struct { + adns_query back, next; + } siblings; + struct { + allocnode *head, *tail; + } allocations; + int interim_allocd, preserved_allocd; + void *final_allocspace; + + const typeinfo *typei; + byte *query_dgram; + int query_dglen; + + vbuf vb; + /* General-purpose messing-about buffer. + * Wherever a `big' interface is crossed, this may be corrupted/changed + * unless otherwise specified. + */ + + adns_answer *answer; + /* This is allocated when a query is submitted, to avoid being unable + * to relate errors to queries if we run out of memory. During + * query processing status, rrs is 0. cname is set if + * we found a cname (this corresponds to cname_dgram in the query + * structure). type is set from the word go. nrrs and rrs + * are set together, when we find how many rrs there are. + * owner is set during querying unless we're doing searchlist, + * in which case it is set only when we find an answer. + */ + + byte *cname_dgram; + int cname_dglen, cname_begin; + /* If non-0, has been allocated using . */ + + vbuf search_vb; + int search_origlen, search_pos, search_doneabs; + /* Used by the searching algorithm. The query domain in textual form + * is copied into the vbuf, and _origlen set to its length. Then + * we walk the searchlist, if we want to. _pos says where we are + * (next entry to try), and _doneabs says whether we've done the + * absolute query yet (0=not yet, 1=done, -1=must do straight away, + * but not done yet). If flags doesn't have adns_qf_search then + * the vbuf is initialised but empty and everything else is zero. + */ + + int id, flags, retries; + int udpnextserver; + unsigned long udpsent; /* bitmap indexed by server */ + struct timeval timeout; + time_t expires; /* Earliest expiry time of any record we used. */ + + qcontext ctx; + + /* Possible states: + * + * state Queue child id nextudpserver udpsent tcpfailed + * + * tosend NONE null >=0 0 zero zero + * tosend udpw null >=0 any nonzero zero + * tosend NONE null >=0 any nonzero zero + * + * tcpw tcpw null >=0 irrelevant any any + * + * child childw set >=0 irrelevant irrelevant irrelevant + * child NONE null >=0 irrelevant irrelevant irrelevant + * done output null -1 irrelevant irrelevant irrelevant + * + * Queries are only not on a queue when they are actually being processed. + * Queries in state tcpw/tcpw have been sent (or are in the to-send buffer) + * iff the tcp connection is in state server_ok. + * + * +------------------------+ + * START -----> | tosend/NONE | + * +------------------------+ + * / |\ \ + * too big for UDP / UDP timeout \ \ send via UDP + * send via TCP / more retries \ \ + * when conn'd / desired \ \ + * | | | + * v | v + * +-----------+ +-------------+ + * | tcpw/tcpw | ________ | tosend/udpw | + * +-----------+ \ +-------------+ + * | | | UDP timeout | | + * | | | no more | | + * | | | retries | | + * \ | TCP died | desired | | + * \ \ no more | | | + * \ \ servers | TCP / | + * \ \ to try | timeout / | + * got \ \ v |_ | got + * reply \ _| +------------------+ / reply + * \ | done/output FAIL | / + * \ +------------------+ / + * \ / + * _| |_ + * (..... got reply ....) + * / \ + * need child query/ies / \ no child query + * / \ + * |_ _| + * +---------------+ +----------------+ + * | childw/childw | ----------------> | done/output OK | + * +---------------+ children done +----------------+ + */ +}; + +struct query_queue { + adns_query head, tail; +}; + +struct adns__state { + adns_initflags iflags; + FILE *diagfile; + int configerrno; + struct query_queue udpw, tcpw, childw, output; + adns_query forallnext; + int nextid, udpsocket, tcpsocket; + vbuf tcpsend, tcprecv; + int nservers, nsortlist, nsearchlist, searchndots, tcpserver, + tcprecv_skip; + enum adns__tcpstate { + server_disconnected, server_connecting, + server_ok, server_broken + } tcpstate; + struct timeval tcptimeout; + /* This will have tv_sec==0 if it is not valid. It will always be + * valid if tcpstate _connecting. When _ok, it will be nonzero if + * we are idle (ie, tcpw queue is empty), in which case it is the + * absolute time when we will close the connection. + */ + struct sigaction stdsigpipe; + sigset_t stdsigmask; + struct pollfd pollfds_buf[MAX_POLLFDS]; + struct server { + struct in_addr addr; + } servers[MAXSERVERS]; + struct sortlist { + struct in_addr base, mask; + } sortlist[MAXSORTLIST]; + char **searchlist; +}; + +/* From setup.c: */ + +int adns__setnonblock(adns_state ads, int fd); /* => errno value */ + +/* From general.c: */ + +void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, + int serv, adns_query qu, const char *fmt, va_list al); + +void adns__debug(adns_state ads, int serv, adns_query qu, + const char *fmt, ...) PRINTFFORMAT(4, 5); +void adns__warn(adns_state ads, int serv, adns_query qu, + const char *fmt, ...) PRINTFFORMAT(4, 5); +void adns__diag(adns_state ads, int serv, adns_query qu, + const char *fmt, ...) PRINTFFORMAT(4, 5); + +int adns__vbuf_ensure(vbuf * vb, int want); +int adns__vbuf_appendstr(vbuf * vb, const char *data); /* does not include nul */ +int adns__vbuf_append(vbuf * vb, const byte * data, int len); +/* 1=>success, 0=>realloc failed */ +void adns__vbuf_appendq(vbuf * vb, const byte * data, int len); +void adns__vbuf_init(vbuf * vb); +void adns__vbuf_free(vbuf * vb); + +const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, + vbuf * vb, const byte * dgram, int dglen, + int cbyte); +/* Unpicks a domain in a datagram and returns a string suitable for + * printing it as. Never fails - if an error occurs, it will + * return some kind of string describing the error. + * + * serv may be -1 and qu may be 0. vb must have been initialised, + * and will be left in an arbitrary consistent state. + * + * Returns either vb->buf, or a pointer to a string literal. Do not modify + * vb before using the return value. + */ + +void adns__isort(void *array, int nobjs, int sz, void *tempbuf, + int (*needswap) (void *context, const void *a, + const void *b), void *context); +/* Does an insertion sort of array which must contain nobjs objects + * each sz bytes long. tempbuf must point to a buffer at least + * sz bytes long. needswap should return !0 if a>b (strictly, ie + * wrong order) 0 if a<=b (ie, order is fine). + */ + +void adns__sigpipe_protect(adns_state); +void adns__sigpipe_unprotect(adns_state); +/* If SIGPIPE protection is not disabled, will block all signals except + * SIGPIPE, and set SIGPIPE's disposition to SIG_IGN. (And then restore.) + * Each call to _protect must be followed by a call to _unprotect before + * any significant amount of code gets to run, since the old signal mask + * is stored in the adns structure. + */ + +/* From transmit.c: */ + +adns_status adns__mkquery(adns_state ads, vbuf * vb, int *id_r, + const char *owner, int ol, + const typeinfo * typei, adns_queryflags flags); +/* Assembles a query packet in vb. A new id is allocated and returned. + */ + +adns_status adns__mkquery_frdgram(adns_state ads, vbuf * vb, int *id_r, + const byte * qd_dgram, int qd_dglen, + int qd_begin, adns_rrtype type, + adns_queryflags flags); +/* Same as adns__mkquery, but takes the owner domain from an existing datagram. + * That domain must be correct and untruncated. + */ + +void adns__querysend_tcp(adns_query qu, struct timeval now); +/* Query must be in state tcpw/tcpw; it will be sent if possible and + * no further processing can be done on it for now. The connection + * might be broken, but no reconnect will be attempted. + */ + +void adns__query_send(adns_query qu, struct timeval now); +/* Query must be in state tosend/NONE; it will be moved to a new state, + * and no further processing can be done on it for now. + * (Resulting state is one of udp/timew, tcpwait/timew (if server not connected), + * tcpsent/timew, child/childw or done/output.) + * __query_send may decide to use either UDP or TCP depending whether + * _qf_usevc is set (or has become set) and whether the query is too + * large. + */ + +/* From query.c: */ + +adns_status adns__internal_submit(adns_state ads, adns_query * query_r, + const typeinfo * typei, vbuf * qumsg_vb, + int id, adns_queryflags flags, + struct timeval now, + const qcontext * ctx); +/* Submits a query (for internal use, called during external submits). + * + * The new query is returned in *query_r, or we return adns_s_nomemory. + * + * The query datagram should already have been assembled in qumsg_vb; + * the memory for it is _taken over_ by this routine whether it + * succeeds or fails (if it succeeds, the vbuf is reused for qu->vb). + * + * *ctx is copied byte-for-byte into the query. + * + * When the child query is done, ctx->callback will be called. The + * child will already have been taken off both the global list of + * queries in ads and the list of children in the parent. The child + * will be freed when the callback returns. The parent will have been + * taken off the global childw queue. + * + * The callback should either call adns__query_done, if it is + * complete, or adns__query_fail, if an error has occurred, in which + * case the other children (if any) will be cancelled. If the parent + * has more unfinished children (or has just submitted more) then the + * callback may choose to wait for them - it must then put the parent + * back on the childw queue. + */ + +void adns__search_next(adns_state ads, adns_query qu, struct timeval now); +/* Walks down the searchlist for a query with adns_qf_search. + * The query should have just had a negative response, or not had + * any queries sent yet, and should not be on any queue. + * The query_dgram if any will be freed and forgotten and a new + * one constructed from the search_* members of the query. + * + * Cannot fail (in case of error, calls adns__query_fail). + */ + +void *adns__alloc_interim(adns_query qu, size_t sz); +void *adns__alloc_preserved(adns_query qu, size_t sz); +/* Allocates some memory, and records which query it came from + * and how much there was. + * + * If an error occurs in the query, all the memory from _interim is + * simply freed. If the query succeeds, one large buffer will be made + * which is big enough for all these allocations, and then + * adns__alloc_final will get memory from this buffer. + * + * _alloc_interim can fail (and return 0). + * The caller must ensure that the query is failed. + * + * The memory from _preserved is is kept and transferred into the + * larger buffer - unless we run out of memory, in which case it too + * is freed. When you use _preserved you have to add code to the + * x_nomem error exit case in adns__makefinal_query to clear out the + * pointers you made to those allocations, because that's when they're + * thrown away; you should also make a note in the declaration of + * those pointer variables, to note that they are _preserved rather + * than _interim. If they're in the answer, note it here: + * answer->cname and answer->owner are _preserved. + */ + +void adns__transfer_interim(adns_query from, adns_query to, void *block, + size_t sz); +/* Transfers an interim allocation from one query to another, so that + * the `to' query will have room for the data when we get to makefinal + * and so that the free will happen when the `to' query is freed + * rather than the `from' query. + * + * It is legal to call adns__transfer_interim with a null pointer; this + * has no effect. + * + * _transfer_interim also ensures that the expiry time of the `to' query + * is no later than that of the `from' query, so that child queries' + * TTLs get inherited by their parents. + */ + +void *adns__alloc_mine(adns_query qu, size_t sz); +/* Like _interim, but does not record the length for later + * copying into the answer. This just ensures that the memory + * will be freed when we're done with the query. + */ + +void *adns__alloc_final(adns_query qu, size_t sz); +/* Cannot fail, and cannot return 0. + */ + +void adns__makefinal_block(adns_query qu, void **blpp, size_t sz); +void adns__makefinal_str(adns_query qu, char **strp); + +void adns__reset_preserved(adns_query qu); +/* Resets all of the memory management stuff etc. to take account of + * only the _preserved stuff from _alloc_preserved. Used when we find + * an error somewhere and want to just report the error (with perhaps + * CNAME, owner, etc. info), and also when we're halfway through RRs + * in a datagram and discover that we need to retry the query. + */ + +void adns__query_done(adns_query qu); +void adns__query_fail(adns_query qu, adns_status stat); + +/* From reply.c: */ + +void adns__procdgram(adns_state ads, const byte * dgram, int len, + int serv, int viatcp, struct timeval now); +/* This function is allowed to cause new datagrams to be constructed + * and sent, or even new queries to be started. However, + * query-sending functions are not allowed to call any general event + * loop functions in case they accidentally call this. + * + * Ie, receiving functions may call sending functions. + * Sending functions may NOT call receiving functions. + */ + +/* From types.c: */ + +const typeinfo *adns__findtype(adns_rrtype type); + +/* From parse.c: */ + +typedef struct { + adns_state ads; + adns_query qu; + int serv; + const byte *dgram; + int dglen, max, cbyte, namelen; + int *dmend_r; +} findlabel_state; + +void adns__findlabel_start(findlabel_state * fls, adns_state ads, + int serv, adns_query qu, + const byte * dgram, int dglen, int max, + int dmbegin, int *dmend_rlater); +/* Finds labels in a domain in a datagram. + * + * Call this routine first. + * dmend_rlater may be null. ads (and of course fls) may not be. + * serv may be -1, qu may be null - they are for error reporting. + */ + +adns_status adns__findlabel_next(findlabel_state * fls, int *lablen_r, + int *labstart_r); +/* Then, call this one repeatedly. + * + * It will return adns_s_ok if all is well, and tell you the length + * and start of successive labels. labstart_r may be null, but + * lablen_r must not be. + * + * After the last label, it will return with *lablen_r zero. + * Do not then call it again; instead, just throw away the findlabel_state. + * + * *dmend_rlater will have been set to point to the next part of + * the datagram after the label (or after the uncompressed part, + * if compression was used). *namelen_rlater will have been set + * to the length of the domain name (total length of labels plus + * 1 for each intervening dot). + * + * If the datagram appears to be truncated, *lablen_r will be -1. + * *dmend_rlater, *labstart_r and *namelen_r may contain garbage. + * Do not call _next again. + * + * There may also be errors, in which case *dmend_rlater, + * *namelen_rlater, *lablen_r and *labstart_r may contain garbage. + * Do not then call findlabel_next again. + */ + +typedef enum { + pdf_quoteok = 0x001 +} parsedomain_flags; + +adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, + vbuf * vb, parsedomain_flags flags, + const byte * dgram, int dglen, + int *cbyte_io, int max); +/* vb must already have been initialised; it will be reset if necessary. + * If there is truncation, vb->used will be set to 0; otherwise + * (if there is no error) vb will be null-terminated. + * If there is an error vb and *cbyte_io may be left indeterminate. + * + * serv may be -1 and qu may be 0 - they are used for error reporting only. + */ + +adns_status adns__parse_domain_more(findlabel_state * fls, adns_state ads, + adns_query qu, vbuf * vb, + parsedomain_flags flags, + const byte * dgram); +/* Like adns__parse_domain, but you pass it a pre-initialised findlabel_state, + * for continuing an existing domain or some such of some kind. Also, unlike + * _parse_domain, the domain data will be appended to vb, rather than replacing + * the existing contents. + */ + +adns_status adns__findrr(adns_query qu, int serv, + const byte * dgram, int dglen, int *cbyte_io, + int *type_r, int *class_r, unsigned long *ttl_r, + int *rdlen_r, int *rdstart_r, + int *ownermatchedquery_r); +/* Finds the extent and some of the contents of an RR in a datagram + * and does some checks. The datagram is *dgram, length dglen, and + * the RR starts at *cbyte_io (which is updated afterwards to point + * to the end of the RR). + * + * The type, class, TTL and RRdata length and start are returned iff + * the corresponding pointer variables are not null. type_r, class_r + * and ttl_r may not be null. The TTL will be capped. + * + * If ownermatchedquery_r != 0 then the owner domain of this + * RR will be compared with that in the query (or, if the query + * has gone to a CNAME lookup, with the canonical name). + * In this case, *ownermatchedquery_r will be set to 0 or 1. + * The query datagram (or CNAME datagram) MUST be valid and not truncated. + * + * If there is truncation then *type_r will be set to -1 and + * *cbyte_io, *class_r, *rdlen_r, *rdstart_r and *eo_matched_r will be + * undefined. + * + * qu must obviously be non-null. + * + * If an error is returned then *type_r will be undefined too. + */ + +adns_status adns__findrr_anychk(adns_query qu, int serv, + const byte * dgram, int dglen, + int *cbyte_io, int *type_r, int *class_r, + unsigned long *ttl_r, int *rdlen_r, + int *rdstart_r, const byte * eo_dgram, + int eo_dglen, int eo_cbyte, + int *eo_matched_r); +/* Like adns__findrr_checked, except that the datagram and + * owner to compare with can be specified explicitly. + * + * If the caller thinks they know what the owner of the RR ought to + * be they can pass in details in eo_*: this is another (or perhaps + * the same datagram), and a pointer to where the putative owner + * starts in that datagram. In this case *eo_matched_r will be set + * to 1 if the datagram matched or 0 if it did not. Either + * both eo_dgram and eo_matched_r must both be non-null, or they + * must both be null (in which case eo_dglen and eo_cbyte will be ignored). + * The eo datagram and contained owner domain MUST be valid and + * untruncated. + */ + +void adns__update_expires(adns_query qu, unsigned long ttl, + struct timeval now); +/* Updates the `expires' field in the query, so that it doesn't exceed + * now + ttl. + */ + +int vbuf__append_quoted1035(vbuf * vb, const byte * buf, int len); + +/* From event.c: */ + +void adns__tcp_broken(adns_state ads, const char *what, const char *why); +/* what and why may be both 0, or both non-0. */ + +void adns__tcp_tryconnect(adns_state ads, struct timeval now); + +void adns__autosys(adns_state ads, struct timeval now); +/* Make all the system calls we want to if the application wants us to. + * Must not be called from within adns internal processing functions, + * lest we end up in recursive descent ! + */ + +void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io, + struct timeval *tv_buf); + +int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]); +void adns__fdevents(adns_state ads, + const struct pollfd *pollfds, int npollfds, + int maxfd, const fd_set * readfds, + const fd_set * writefds, const fd_set * exceptfds, + struct timeval now, int *r_r); +int adns__internal_check(adns_state ads, + adns_query * query_io, + adns_answer ** answer, void **context_r); + +void adns__timeouts(adns_state ads, int act, + struct timeval **tv_io, struct timeval *tvbuf, + struct timeval now); +/* If act is !0, then this will also deal with the TCP connection + * if previous events broke it or require it to be connected. + */ + +/* From check.c: */ + +void adns__consistency(adns_state ads, adns_query qu, + consistency_checks cc); + +/* Useful static inline functions: */ + +static inline int ctype_whitespace(int c) +{ + return c == ' ' || c == '\n' || c == '\t'; +} +static inline int ctype_digit(int c) +{ + return c >= '0' && c <= '9'; +} +static inline int ctype_alpha(int c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} +static inline int ctype_822special(int c) +{ + return strchr("()<>@,;:\\\".[]", c) != 0; +} +static inline int ctype_domainunquoted(int c) +{ + return ctype_alpha(c) || ctype_digit(c) + || (strchr("-_/+", c) != 0); +} + +static inline int errno_resources(int e) +{ + return e == ENOMEM || e == ENOBUFS; +} + +/* Useful macros */ + +#define MEM_ROUND(sz) \ + (( ((sz)+sizeof(union maxalign)-1) / sizeof(union maxalign) ) \ + * sizeof(union maxalign) ) + +#define GETIL_B(cb) (((dgram)[(cb)++]) & 0x0ff) +#define GET_B(cb,tv) ((tv)= GETIL_B((cb))) +#define GET_W(cb,tv) ((tv)=0, (tv)|=(GETIL_B((cb))<<8), (tv)|=GETIL_B(cb), (tv)) +#define GET_L(cb,tv) ( (tv)=0, \ + (tv)|=(GETIL_B((cb))<<24), \ + (tv)|=(GETIL_B((cb))<<16), \ + (tv)|=(GETIL_B((cb))<<8), \ + (tv)|=GETIL_B(cb), \ + (tv) ) + +#endif diff --git a/adns/parse.c b/adns/parse.c new file mode 100644 index 0000000..241c4f1 --- /dev/null +++ b/adns/parse.c @@ -0,0 +1,332 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * parse.c + * - parsing assistance functions (mainly for domains inside datagrams) + */ +/* + * This file is + * Copyright (C) 1997-2000 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "internal.h" + +int vbuf__append_quoted1035(vbuf * vb, const byte * buf, int len) +{ + char qbuf[10]; + int i, ch; + + while (len) { + qbuf[0] = 0; + for (i = 0; i < len; i++) { + ch = buf[i]; + if (ch <= ' ' || ch >= 127) { + sprintf(qbuf, "\\%03o", ch); + break; + } else if (!ctype_domainunquoted(ch)) { + sprintf(qbuf, "\\%c", ch); + break; + } + } + if (!adns__vbuf_append(vb, buf, i) + || !adns__vbuf_append(vb, qbuf, strlen(qbuf))) + return 0; + if (i < len) + i++; + buf += i; + len -= i; + } + return 1; +} + +void adns__findlabel_start(findlabel_state * fls, adns_state ads, + int serv, adns_query qu, + const byte * dgram, int dglen, int max, + int dmbegin, int *dmend_rlater) +{ + fls->ads = ads; + fls->qu = qu; + fls->serv = serv; + fls->dgram = dgram; + fls->dglen = dglen; + fls->max = max; + fls->cbyte = dmbegin; + fls->namelen = 0; + fls->dmend_r = dmend_rlater; +} + +adns_status adns__findlabel_next(findlabel_state * fls, + int *lablen_r, int *labstart_r) +{ + int lablen, jumpto; + const char *dgram; + + dgram = fls->dgram; + for (;;) { + if (fls->cbyte >= fls->dglen) + goto x_truncated; + if (fls->cbyte >= fls->max) + goto x_badresponse; + GET_B(fls->cbyte, lablen); + if (!(lablen & 0x0c0)) + break; + if ((lablen & 0x0c0) != 0x0c0) + return adns_s_unknownformat; + if (fls->cbyte >= fls->dglen) + goto x_truncated; + if (fls->cbyte >= fls->max) + goto x_badresponse; + GET_B(fls->cbyte, jumpto); + jumpto |= (lablen & 0x3f) << 8; + if (fls->dmend_r) + *(fls->dmend_r) = fls->cbyte; + fls->cbyte = jumpto; + fls->dmend_r = 0; + fls->max = fls->dglen + 1; + } + if (labstart_r) + *labstart_r = fls->cbyte; + if (lablen) { + if (fls->namelen) + fls->namelen++; + fls->namelen += lablen; + if (fls->namelen > DNS_MAXDOMAIN) + return adns_s_answerdomaintoolong; + fls->cbyte += lablen; + if (fls->cbyte > fls->dglen) + goto x_truncated; + if (fls->cbyte > fls->max) + goto x_badresponse; + } else { + if (fls->dmend_r) + *(fls->dmend_r) = fls->cbyte; + } + *lablen_r = lablen; + return adns_s_ok; + + x_truncated: + *lablen_r = -1; + return adns_s_ok; + + x_badresponse: + adns__diag(fls->ads, fls->serv, fls->qu, + "label in domain runs beyond end of domain"); + return adns_s_invalidresponse; +} + +adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu, + vbuf * vb, adns_queryflags flags, + const byte * dgram, int dglen, + int *cbyte_io, int max) +{ + findlabel_state fls; + + adns__findlabel_start(&fls, ads, serv, qu, dgram, dglen, max, + *cbyte_io, cbyte_io); + vb->used = 0; + return adns__parse_domain_more(&fls, ads, qu, vb, flags, dgram); +} + +adns_status adns__parse_domain_more(findlabel_state * fls, adns_state ads, + adns_query qu, vbuf * vb, + parsedomain_flags flags, + const byte * dgram) +{ + int lablen, labstart, i, ch, first; + adns_status st; + + first = 1; + for (;;) { + st = adns__findlabel_next(fls, &lablen, &labstart); + if (st) + return st; + if (lablen < 0) { + vb->used = 0; + return adns_s_ok; + } + if (!lablen) + break; + if (first) { + first = 0; + } else { + if (!adns__vbuf_append(vb, ".", 1)) + return adns_s_nomemory; + } + if (flags & pdf_quoteok) { + if (!vbuf__append_quoted1035 + (vb, dgram + labstart, lablen)) + return adns_s_nomemory; + } else { + ch = dgram[labstart]; + if (!ctype_alpha(ch) && !ctype_digit(ch)) + return adns_s_answerdomaininvalid; + for (i = labstart + 1; i < labstart + lablen; i++) { + ch = dgram[i]; + if (ch != '-' && !ctype_alpha(ch) + && !ctype_digit(ch)) + return adns_s_answerdomaininvalid; + } + if (!adns__vbuf_append + (vb, dgram + labstart, lablen)) + return adns_s_nomemory; + } + } + if (!adns__vbuf_append(vb, "", 1)) + return adns_s_nomemory; + return adns_s_ok; +} + +adns_status adns__findrr_anychk(adns_query qu, int serv, + const byte * dgram, int dglen, + int *cbyte_io, int *type_r, int *class_r, + unsigned long *ttl_r, int *rdlen_r, + int *rdstart_r, const byte * eo_dgram, + int eo_dglen, int eo_cbyte, + int *eo_matched_r) +{ + findlabel_state fls, eo_fls; + int cbyte; + + int tmp, rdlen, mismatch; + unsigned long ttl; + int lablen, labstart, ch; + int eo_lablen, eo_labstart, eo_ch; + adns_status st; + + cbyte = *cbyte_io; + + adns__findlabel_start(&fls, qu->ads, serv, qu, dgram, dglen, dglen, + cbyte, &cbyte); + if (eo_dgram) { + adns__findlabel_start(&eo_fls, qu->ads, -1, 0, eo_dgram, + eo_dglen, eo_dglen, eo_cbyte, 0); + mismatch = 0; + } else { + mismatch = 1; + } + + for (;;) { + st = adns__findlabel_next(&fls, &lablen, &labstart); + if (st) + return st; + if (lablen < 0) + goto x_truncated; + + if (!mismatch) { + st = adns__findlabel_next(&eo_fls, &eo_lablen, + &eo_labstart); + assert(!st); + assert(eo_lablen >= 0); + if (lablen != eo_lablen) + mismatch = 1; + while (!mismatch && eo_lablen-- > 0) { + ch = dgram[labstart++]; + if (ctype_alpha(ch)) + ch &= ~32; + eo_ch = eo_dgram[eo_labstart++]; + if (ctype_alpha(eo_ch)) + eo_ch &= ~32; + if (ch != eo_ch) + mismatch = 1; + } + } + if (!lablen) + break; + } + if (eo_matched_r) + *eo_matched_r = !mismatch; + + if (cbyte + 10 > dglen) + goto x_truncated; + GET_W(cbyte, tmp); + *type_r = tmp; + GET_W(cbyte, tmp); + *class_r = tmp; + + GET_L(cbyte, ttl); + if (ttl > MAXTTLBELIEVE) + ttl = MAXTTLBELIEVE; + *ttl_r = ttl; + + GET_W(cbyte, rdlen); + if (rdlen_r) + *rdlen_r = rdlen; + if (rdstart_r) + *rdstart_r = cbyte; + cbyte += rdlen; + if (cbyte > dglen) + goto x_truncated; + *cbyte_io = cbyte; + return adns_s_ok; + + x_truncated: + *type_r = -1; + return 0; +} + +adns_status adns__findrr(adns_query qu, int serv, + const byte * dgram, int dglen, int *cbyte_io, + int *type_r, int *class_r, unsigned long *ttl_r, + int *rdlen_r, int *rdstart_r, + int *ownermatchedquery_r) +{ + if (!ownermatchedquery_r) { + return adns__findrr_anychk(qu, serv, + dgram, dglen, cbyte_io, + type_r, class_r, ttl_r, rdlen_r, + rdstart_r, 0, 0, 0, 0); + } else if (!qu->cname_dgram) { + return adns__findrr_anychk(qu, serv, + dgram, dglen, cbyte_io, + type_r, class_r, ttl_r, rdlen_r, + rdstart_r, qu->query_dgram, + qu->query_dglen, DNS_HDRSIZE, + ownermatchedquery_r); + } else { + return adns__findrr_anychk(qu, serv, + dgram, dglen, cbyte_io, + type_r, class_r, ttl_r, rdlen_r, + rdstart_r, qu->cname_dgram, + qu->cname_dglen, + qu->cname_begin, + ownermatchedquery_r); + } +} diff --git a/adns/query.c b/adns/query.c new file mode 100644 index 0000000..bde2a22 --- /dev/null +++ b/adns/query.c @@ -0,0 +1,684 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * query.c + * - overall query management (allocation, completion) + * - per-query memory management + * - query submission and cancellation (user-visible and internal) + */ +/* + * This file is + * Copyright (C) 1997-2000 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "internal.h" + +#include +#include +#include + +#include + +#include "internal.h" + +static adns_query query_alloc(adns_state ads, const typeinfo * typei, + adns_queryflags flags, struct timeval now) +{ + /* Allocate a virgin query and return it. */ + adns_query qu; + + qu = malloc(sizeof(*qu)); + if (!qu) + return 0; + qu->answer = malloc(sizeof(*qu->answer)); + if (!qu->answer) { + free(qu); + return 0; + } + + qu->ads = ads; + qu->state = query_tosend; + qu->back = qu->next = qu->parent = 0; + ALIST_INIT(qu->children); + ALINK_INIT(qu->siblings); + ALIST_INIT(qu->allocations); + qu->interim_allocd = 0; + qu->preserved_allocd = 0; + qu->final_allocspace = 0; + + qu->typei = typei; + qu->query_dgram = 0; + qu->query_dglen = 0; + adns__vbuf_init(&qu->vb); + + qu->cname_dgram = 0; + qu->cname_dglen = qu->cname_begin = 0; + + adns__vbuf_init(&qu->search_vb); + qu->search_origlen = qu->search_pos = qu->search_doneabs = 0; + + qu->id = -2; /* will be overwritten with real id before we leave adns */ + qu->flags = flags; + qu->retries = 0; + qu->udpnextserver = 0; + qu->udpsent = 0; + timerclear(&qu->timeout); + qu->expires = now.tv_sec + MAXTTLBELIEVE; + + memset(&qu->ctx, 0, sizeof(qu->ctx)); + + qu->answer->status = adns_s_ok; + qu->answer->cname = qu->answer->owner = 0; + qu->answer->type = typei->type; + qu->answer->expires = -1; + qu->answer->nrrs = 0; + qu->answer->rrs.untyped = 0; + qu->answer->rrsz = typei->rrsz; + + return qu; +} + +static void query_submit(adns_state ads, adns_query qu, + const typeinfo * typei, vbuf * qumsg_vb, int id, + adns_queryflags flags, struct timeval now) +{ + /* Fills in the query message in for a previously-allocated query, + * and submits it. Cannot fail. Takes over the memory for qumsg_vb. + */ + + qu->vb = *qumsg_vb; + adns__vbuf_init(qumsg_vb); + + qu->query_dgram = malloc(qu->vb.used); + if (!qu->query_dgram) { + adns__query_fail(qu, adns_s_nomemory); + return; + } + + qu->id = id; + qu->query_dglen = qu->vb.used; + memcpy(qu->query_dgram, qu->vb.buf, qu->vb.used); + + adns__query_send(qu, now); +} + +adns_status adns__internal_submit(adns_state ads, adns_query * query_r, + const typeinfo * typei, vbuf * qumsg_vb, + int id, adns_queryflags flags, + struct timeval now, const qcontext * ctx) +{ + adns_query qu; + + qu = query_alloc(ads, typei, flags, now); + if (!qu) { + adns__vbuf_free(qumsg_vb); + return adns_s_nomemory; + } + *query_r = qu; + + memcpy(&qu->ctx, ctx, sizeof(qu->ctx)); + query_submit(ads, qu, typei, qumsg_vb, id, flags, now); + + return adns_s_ok; +} + +static void query_simple(adns_state ads, adns_query qu, + const char *owner, int ol, + const typeinfo * typei, adns_queryflags flags, + struct timeval now) +{ + vbuf vb_new; + int id; + adns_status stat; + + stat = adns__mkquery(ads, &qu->vb, &id, owner, ol, typei, flags); + if (stat) { + if (stat == adns_s_querydomaintoolong + && (flags & adns_qf_search)) { + adns__search_next(ads, qu, now); + return; + } else { + adns__query_fail(qu, stat); + return; + } + } + + vb_new = qu->vb; + adns__vbuf_init(&qu->vb); + query_submit(ads, qu, typei, &vb_new, id, flags, now); +} + +void adns__search_next(adns_state ads, adns_query qu, struct timeval now) +{ + const char *nextentry; + adns_status stat; + + if (qu->search_doneabs < 0) { + nextentry = 0; + qu->search_doneabs = 1; + } else { + if (qu->search_pos >= ads->nsearchlist) { + if (qu->search_doneabs) { + stat = adns_s_nxdomain; + goto x_fail; + return; + } else { + nextentry = 0; + qu->search_doneabs = 1; + } + } else { + nextentry = ads->searchlist[qu->search_pos++]; + } + } + + qu->search_vb.used = qu->search_origlen; + if (nextentry) { + if (!adns__vbuf_append(&qu->search_vb, ".", 1) || + !adns__vbuf_appendstr(&qu->search_vb, nextentry)) { + stat = adns_s_nomemory; + goto x_fail; + } + } + + free(qu->query_dgram); + qu->query_dgram = 0; + qu->query_dglen = 0; + + query_simple(ads, qu, qu->search_vb.buf, qu->search_vb.used, + qu->typei, qu->flags, now); + return; + + x_fail: + adns__query_fail(qu, stat); +} + +static int save_owner(adns_query qu, const char *owner, int ol) +{ + /* Returns 1 if OK, otherwise there was no memory. */ + adns_answer *ans; + + ans = qu->answer; + assert(!ans->owner); + + ans->owner = adns__alloc_preserved(qu, ol + 1); + if (!ans->owner) + return 0; + + memcpy(ans->owner, owner, ol); + ans->owner[ol] = 0; + return 1; +} + +int adns_submit(adns_state ads, + const char *owner, + adns_rrtype type, + adns_queryflags flags, void *context, adns_query * query_r) +{ + int r, ol, ndots; + adns_status stat; + const typeinfo *typei; + struct timeval now; + adns_query qu; + const char *p; + + adns__consistency(ads, 0, cc_entex); + + typei = adns__findtype(type); + if (!typei) + return ENOSYS; + + r = gettimeofday(&now, 0); + if (r) + goto x_errno; + qu = query_alloc(ads, typei, flags, now); + if (!qu) + goto x_errno; + + qu->ctx.ext = context; + qu->ctx.callback = 0; + memset(&qu->ctx.info, 0, sizeof(qu->ctx.info)); + + *query_r = qu; + + ol = strlen(owner); + if (!ol) { + stat = adns_s_querydomaininvalid; + goto x_adnsfail; + } + if (ol > DNS_MAXDOMAIN + 1) { + stat = adns_s_querydomaintoolong; + goto x_adnsfail; + } + + if (ol >= 1 && owner[ol - 1] == '.' + && (ol < 2 || owner[ol - 2] != '\\')) { + flags &= ~adns_qf_search; + qu->flags = flags; + ol--; + } + + if (flags & adns_qf_search) { + r = adns__vbuf_append(&qu->search_vb, owner, ol); + if (!r) { + stat = adns_s_nomemory; + goto x_adnsfail; + } + + for (ndots = 0, p = owner; (p = strchr(p, '.')); + p++, ndots++); + qu->search_doneabs = (ndots >= ads->searchndots) ? -1 : 0; + qu->search_origlen = ol; + adns__search_next(ads, qu, now); + } else { + if (flags & adns_qf_owner) { + if (!save_owner(qu, owner, ol)) { + stat = adns_s_nomemory; + goto x_adnsfail; + } + } + query_simple(ads, qu, owner, ol, typei, flags, now); + } + adns__autosys(ads, now); + adns__consistency(ads, qu, cc_entex); + return 0; + + x_adnsfail: + adns__query_fail(qu, stat); + adns__consistency(ads, qu, cc_entex); + return 0; + + x_errno: + r = errno; + assert(r); + adns__consistency(ads, 0, cc_entex); + return r; +} + +int adns_submit_reverse_any(adns_state ads, + const struct sockaddr *addr, + const char *zone, + adns_rrtype type, + adns_queryflags flags, + void *context, adns_query * query_r) +{ + const unsigned char *iaddr; + char *buf, *buf_free; + char shortbuf[100]; + int r, lreq; + + flags &= ~adns_qf_search; + + if (addr->sa_family != AF_INET) + return ENOSYS; + iaddr = + (const unsigned char *) &(((const struct sockaddr_in *) addr)-> + sin_addr); + + lreq = strlen(zone) + 4 * 4 + 1; + if (lreq > sizeof(shortbuf)) { + buf = malloc(strlen(zone) + 4 * 4 + 1); + if (!buf) + return errno; + buf_free = buf; + } else { + buf = shortbuf; + buf_free = 0; + } + sprintf(buf, "%d.%d.%d.%d.%s", iaddr[3], iaddr[2], iaddr[1], + iaddr[0], zone); + + r = adns_submit(ads, buf, type, flags, context, query_r); + free(buf_free); + return r; +} + +int adns_submit_reverse(adns_state ads, + const struct sockaddr *addr, + adns_rrtype type, + adns_queryflags flags, + void *context, adns_query * query_r) +{ + if (type != adns_r_ptr && type != adns_r_ptr_raw) + return EINVAL; + return adns_submit_reverse_any(ads, addr, "in-addr.arpa", type, + flags, context, query_r); +} + +int adns_synchronous(adns_state ads, + const char *owner, + adns_rrtype type, + adns_queryflags flags, adns_answer ** answer_r) +{ + adns_query qu; + int r; + + r = adns_submit(ads, owner, type, flags, 0, &qu); + if (r) + return r; + + r = adns_wait(ads, &qu, answer_r, 0); + if (r) + adns_cancel(qu); + + return r; +} + +static void *alloc_common(adns_query qu, size_t sz) +{ + allocnode *an; + + if (!sz) + return qu; /* Any old pointer will do */ + assert(!qu->final_allocspace); + an = malloc(MEM_ROUND(MEM_ROUND(sizeof(*an)) + sz)); + if (!an) + return 0; + LIST_LINK_TAIL(qu->allocations, an); + return (byte *) an + MEM_ROUND(sizeof(*an)); +} + +void *adns__alloc_interim(adns_query qu, size_t sz) +{ + void *rv; + + sz = MEM_ROUND(sz); + rv = alloc_common(qu, sz); + if (!rv) + return 0; + qu->interim_allocd += sz; + return rv; +} + +void *adns__alloc_preserved(adns_query qu, size_t sz) +{ + void *rv; + + sz = MEM_ROUND(sz); + rv = adns__alloc_interim(qu, sz); + if (!rv) + return 0; + qu->preserved_allocd += sz; + return rv; +} + +void *adns__alloc_mine(adns_query qu, size_t sz) +{ + return alloc_common(qu, MEM_ROUND(sz)); +} + +void adns__transfer_interim(adns_query from, adns_query to, void *block, + size_t sz) +{ + allocnode *an; + + if (!block) + return; + an = (void *) ((byte *) block - MEM_ROUND(sizeof(*an))); + + assert(!to->final_allocspace); + assert(!from->final_allocspace); + + LIST_UNLINK(from->allocations, an); + LIST_LINK_TAIL(to->allocations, an); + + sz = MEM_ROUND(sz); + from->interim_allocd -= sz; + to->interim_allocd += sz; + + if (to->expires > from->expires) + to->expires = from->expires; +} + +void *adns__alloc_final(adns_query qu, size_t sz) +{ + /* When we're in the _final stage, we _subtract_ from interim_alloc'd + * each allocation, and use final_allocspace to point to the next free + * bit. + */ + void *rp; + + sz = MEM_ROUND(sz); + rp = qu->final_allocspace; + assert(rp); + qu->interim_allocd -= sz; + assert(qu->interim_allocd >= 0); + qu->final_allocspace = (byte *) rp + sz; + return rp; +} + +static void cancel_children(adns_query qu) +{ + adns_query cqu, ncqu; + + for (cqu = qu->children.head; cqu; cqu = ncqu) { + ncqu = cqu->siblings.next; + adns_cancel(cqu); + } +} + +void adns__reset_preserved(adns_query qu) +{ + assert(!qu->final_allocspace); + cancel_children(qu); + qu->answer->nrrs = 0; + qu->answer->rrs.untyped = 0; + qu->interim_allocd = qu->preserved_allocd; +} + +static void free_query_allocs(adns_query qu) +{ + allocnode *an, *ann; + + cancel_children(qu); + for (an = qu->allocations.head; an; an = ann) { + ann = an->next; + free(an); + } + ALIST_INIT(qu->allocations); + adns__vbuf_free(&qu->vb); + adns__vbuf_free(&qu->search_vb); + free(qu->query_dgram); + qu->query_dgram = 0; +} + +void adns_cancel(adns_query qu) +{ + adns_state ads; + + ads = qu->ads; + adns__consistency(ads, qu, cc_entex); + if (qu->parent) + LIST_UNLINK_PART(qu->parent->children, qu, siblings.); + switch (qu->state) { + case query_tosend: + LIST_UNLINK(ads->udpw, qu); + break; + case query_tcpw: + LIST_UNLINK(ads->tcpw, qu); + break; + case query_childw: + LIST_UNLINK(ads->childw, qu); + break; + case query_done: + LIST_UNLINK(ads->output, qu); + break; + default: + abort(); + } + free_query_allocs(qu); + free(qu->answer); + free(qu); + adns__consistency(ads, 0, cc_entex); +} + +void adns__update_expires(adns_query qu, unsigned long ttl, + struct timeval now) +{ + time_t max; + + assert(ttl <= MAXTTLBELIEVE); + max = now.tv_sec + ttl; + if (qu->expires < max) + return; + qu->expires = max; +} + +static void makefinal_query(adns_query qu) +{ + adns_answer *ans; + int rrn; + + ans = qu->answer; + + if (qu->interim_allocd) { + ans = + realloc(qu->answer, + MEM_ROUND(MEM_ROUND(sizeof(*ans)) + + qu->interim_allocd)); + if (!ans) + goto x_nomem; + qu->answer = ans; + } + + qu->final_allocspace = (byte *) ans + MEM_ROUND(sizeof(*ans)); + adns__makefinal_str(qu, &ans->cname); + adns__makefinal_str(qu, &ans->owner); + + if (ans->nrrs) { + adns__makefinal_block(qu, &ans->rrs.untyped, + ans->nrrs * ans->rrsz); + + for (rrn = 0; rrn < ans->nrrs; rrn++) + qu->typei->makefinal(qu, + ans->rrs.bytes + + rrn * ans->rrsz); + } + + free_query_allocs(qu); + return; + + x_nomem: + qu->preserved_allocd = 0; + qu->answer->cname = 0; + qu->answer->owner = 0; + adns__reset_preserved(qu); /* (but we just threw away the preserved stuff) */ + + qu->answer->status = adns_s_nomemory; + free_query_allocs(qu); +} + +void adns__query_done(adns_query qu) +{ + adns_answer *ans; + adns_query parent; + + cancel_children(qu); + + qu->id = -1; + ans = qu->answer; + + if (qu->flags & adns_qf_owner && qu->flags & adns_qf_search && + ans->status != adns_s_nomemory) { + if (!save_owner(qu, qu->search_vb.buf, qu->search_vb.used)) { + adns__query_fail(qu, adns_s_nomemory); + return; + } + } + + if (ans->nrrs && qu->typei->diff_needswap) { + if (!adns__vbuf_ensure(&qu->vb, qu->typei->rrsz)) { + adns__query_fail(qu, adns_s_nomemory); + return; + } + adns__isort(ans->rrs.bytes, ans->nrrs, ans->rrsz, + qu->vb.buf, + (int (*)(void *, const void *, const void *)) + qu->typei->diff_needswap, qu->ads); + } + + ans->expires = qu->expires; + parent = qu->parent; + if (parent) { + LIST_UNLINK_PART(parent->children, qu, siblings.); + LIST_UNLINK(qu->ads->childw, parent); + qu->ctx.callback(parent, qu); + free_query_allocs(qu); + free(qu->answer); + free(qu); + } else { + makefinal_query(qu); + LIST_LINK_TAIL(qu->ads->output, qu); + qu->state = query_done; + } +} + +void adns__query_fail(adns_query qu, adns_status stat) +{ + adns__reset_preserved(qu); + qu->answer->status = stat; + adns__query_done(qu); +} + +void adns__makefinal_str(adns_query qu, char **strp) +{ + int l; + char *before, *after; + + before = *strp; + if (!before) + return; + l = strlen(before) + 1; + after = adns__alloc_final(qu, l); + memcpy(after, before, l); + *strp = after; +} + +void adns__makefinal_block(adns_query qu, void **blpp, size_t sz) +{ + void *before, *after; + + before = *blpp; + if (!before) + return; + after = adns__alloc_final(qu, sz); + memcpy(after, before, sz); + *blpp = after; +} diff --git a/adns/reply.c b/adns/reply.c new file mode 100644 index 0000000..bb8a0b6 --- /dev/null +++ b/adns/reply.c @@ -0,0 +1,497 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * reply.c + * - main handling and parsing routine for received datagrams + */ +/* + * This file is + * Copyright (C) 1997-2000 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include + +#include "internal.h" + +void adns__procdgram(adns_state ads, const byte * dgram, int dglen, + int serv, int viatcp, struct timeval now) +{ + int cbyte, rrstart, wantedrrs, rri, foundsoa, foundns, cname_here; + int id, f1, f2, qdcount, ancount, nscount, arcount; + int flg_ra, flg_rd, flg_tc, flg_qr, opcode; + int rrtype, rrclass, rdlength, rdstart; + int anstart, nsstart, arstart; + int ownermatched, l, nrrs; + unsigned long ttl, soattl; + const typeinfo *typei; + adns_query qu, nqu; + dns_rcode rcode; + adns_status st; + vbuf tempvb; + byte *newquery, *rrsdata; + parseinfo pai; + + if (dglen < DNS_HDRSIZE) { + adns__diag(ads, serv, 0, + "received datagram too short for message header (%d)", + dglen); + return; + } + cbyte = 0; + GET_W(cbyte, id); + GET_B(cbyte, f1); + GET_B(cbyte, f2); + GET_W(cbyte, qdcount); + GET_W(cbyte, ancount); + GET_W(cbyte, nscount); + GET_W(cbyte, arcount); + assert(cbyte == DNS_HDRSIZE); + + flg_qr = f1 & 0x80; + opcode = (f1 & 0x78) >> 3; + flg_tc = f1 & 0x02; + flg_rd = f1 & 0x01; + flg_ra = f2 & 0x80; + rcode = (f2 & 0x0f); + + cname_here = 0; + + if (!flg_qr) { + adns__diag(ads, serv, 0, + "server sent us a query, not a response"); + return; + } + if (opcode) { + adns__diag(ads, serv, 0, + "server sent us unknown opcode %d (wanted 0=QUERY)", + opcode); + return; + } + + qu = 0; + /* See if we can find the relevant query, or leave qu=0 otherwise ... */ + + if (qdcount == 1) { + for (qu = viatcp ? ads->tcpw.head : ads->udpw.head; qu; + qu = nqu) { + nqu = qu->next; + if (qu->id != id) + continue; + if (dglen < qu->query_dglen) + continue; + if (memcmp(qu->query_dgram + DNS_HDRSIZE, + dgram + DNS_HDRSIZE, + qu->query_dglen - DNS_HDRSIZE)) + continue; + if (viatcp) { + assert(qu->state == query_tcpw); + } else { + assert(qu->state == query_tosend); + if (!(qu->udpsent & (1 << serv))) + continue; + } + break; + } + if (qu) { + /* We're definitely going to do something with this query now */ + if (viatcp) + LIST_UNLINK(ads->tcpw, qu); + else + LIST_UNLINK(ads->udpw, qu); + } + } + + /* If we're going to ignore the packet, we return as soon as we have + * failed the query (if any) and printed the warning message (if + * any). + */ + switch (rcode) { + case rcode_noerror: + case rcode_nxdomain: + break; + case rcode_formaterror: + adns__warn(ads, serv, qu, + "server cannot understand our query (Format Error)"); + if (qu) + adns__query_fail(qu, adns_s_rcodeformaterror); + return; + case rcode_servfail: + if (qu) + adns__query_fail(qu, adns_s_rcodeservfail); + else + adns__debug(ads, serv, qu, + "server failure on unidentifiable query"); + return; + case rcode_notimp: + adns__warn(ads, serv, qu, + "server claims not to implement our query"); + if (qu) + adns__query_fail(qu, adns_s_rcodenotimplemented); + return; + case rcode_refused: + adns__debug(ads, serv, qu, "server refused our query"); + if (qu) + adns__query_fail(qu, adns_s_rcoderefused); + return; + default: + adns__warn(ads, serv, qu, + "server gave unknown response code %d", rcode); + if (qu) + adns__query_fail(qu, adns_s_rcodeunknown); + return; + } + + if (!qu) { + if (!qdcount) { + adns__diag(ads, serv, 0, + "server sent reply without quoting our question"); + } else if (qdcount > 1) { + adns__diag(ads, serv, 0, + "server claimed to answer %d questions with one message", + qdcount); + } else if (ads->iflags & adns_if_debug) { + adns__vbuf_init(&tempvb); + adns__debug(ads, serv, 0, + "reply not found, id %02x, query owner %s", + id, adns__diag_domain(ads, serv, 0, + &tempvb, dgram, + dglen, + DNS_HDRSIZE)); + adns__vbuf_free(&tempvb); + } + return; + } + + /* We're definitely going to do something with this packet and this query now. */ + + anstart = qu->query_dglen; + arstart = -1; + + /* Now, take a look at the answer section, and see if it is complete. + * If it has any CNAMEs we stuff them in the answer. + */ + wantedrrs = 0; + cbyte = anstart; + for (rri = 0; rri < ancount; rri++) { + rrstart = cbyte; + st = adns__findrr(qu, serv, dgram, dglen, &cbyte, + &rrtype, &rrclass, &ttl, &rdlength, + &rdstart, &ownermatched); + if (st) { + adns__query_fail(qu, st); + return; + } + if (rrtype == -1) + goto x_truncated; + + if (rrclass != DNS_CLASS_IN) { + adns__diag(ads, serv, qu, + "ignoring answer RR with wrong class %d (expected IN=%d)", + rrclass, DNS_CLASS_IN); + continue; + } + if (!ownermatched) { + if (ads->iflags & adns_if_debug) { + adns__debug(ads, serv, qu, + "ignoring RR with an unexpected owner %s", + adns__diag_domain(ads, serv, + qu, &qu->vb, + dgram, dglen, + rrstart)); + } + continue; + } + if (rrtype == adns_r_cname && + (qu->typei->type & adns__rrt_typemask) != + adns_r_cname) { + if (qu->flags & adns_qf_cname_forbid) { + adns__query_fail(qu, + adns_s_prohibitedcname); + return; + } else if (qu->cname_dgram) { /* Ignore second and subsequent CNAME(s) */ + adns__debug(ads, serv, qu, + "allegedly canonical name %s is actually alias for %s", + qu->answer->cname, + adns__diag_domain(ads, serv, + qu, &qu->vb, + dgram, dglen, + rdstart)); + adns__query_fail(qu, + adns_s_prohibitedcname); + return; + } else if (wantedrrs) { /* Ignore CNAME(s) after RR(s). */ + adns__debug(ads, serv, qu, + "ignoring CNAME (to %s) coexisting with RR", + adns__diag_domain(ads, serv, + qu, &qu->vb, + dgram, dglen, + rdstart)); + } else { + qu->cname_begin = rdstart; + qu->cname_dglen = dglen; + st = adns__parse_domain(ads, serv, qu, + &qu->vb, + qu-> + flags & + adns_qf_quotefail_cname + ? 0 : pdf_quoteok, + dgram, dglen, + &rdstart, + rdstart + + rdlength); + if (!qu->vb.used) + goto x_truncated; + if (st) { + adns__query_fail(qu, st); + return; + } + l = strlen(qu->vb.buf) + 1; + qu->answer->cname = + adns__alloc_preserved(qu, l); + if (!qu->answer->cname) { + adns__query_fail(qu, + adns_s_nomemory); + return; + } + + qu->cname_dgram = + adns__alloc_mine(qu, dglen); + memcpy(qu->cname_dgram, dgram, dglen); + + memcpy(qu->answer->cname, qu->vb.buf, l); + cname_here = 1; + adns__update_expires(qu, ttl, now); + /* If we find the answer section truncated after this point we restart + * the query at the CNAME; if beforehand then we obviously have to use + * TCP. If there is no truncation we can use the whole answer if + * it contains the relevant info. + */ + } + } else if (rrtype == + (qu->typei->type & adns__rrt_typemask)) { + wantedrrs++; + } else { + adns__debug(ads, serv, qu, + "ignoring answer RR with irrelevant type %d", + rrtype); + } + } + + /* We defer handling truncated responses here, in case there was a CNAME + * which we could use. + */ + if (flg_tc) + goto x_truncated; + + nsstart = cbyte; + + if (!wantedrrs) { + /* Oops, NODATA or NXDOMAIN or perhaps a referral (which would be a problem) */ + + /* RFC2308: NODATA has _either_ a SOA _or_ _no_ NS records in authority section */ + foundsoa = 0; + soattl = 0; + foundns = 0; + for (rri = 0; rri < nscount; rri++) { + rrstart = cbyte; + st = adns__findrr(qu, serv, dgram, dglen, &cbyte, + &rrtype, &rrclass, &ttl, + &rdlength, &rdstart, 0); + if (st) { + adns__query_fail(qu, st); + return; + } + if (rrtype == -1) + goto x_truncated; + if (rrclass != DNS_CLASS_IN) { + adns__diag(ads, serv, qu, + "ignoring authority RR with wrong class %d (expected IN=%d)", + rrclass, DNS_CLASS_IN); + continue; + } + if (rrtype == adns_r_soa_raw) { + foundsoa = 1; + soattl = ttl; + break; + } else if (rrtype == adns_r_ns_raw) { + foundns = 1; + } + } + + if (rcode == rcode_nxdomain) { + /* We still wanted to look for the SOA so we could find the TTL. */ + adns__update_expires(qu, soattl, now); + + if (qu->flags & adns_qf_search) { + adns__search_next(ads, qu, now); + } else { + adns__query_fail(qu, adns_s_nxdomain); + } + return; + } + + if (foundsoa || !foundns) { + /* Aha ! A NODATA response, good. */ + adns__update_expires(qu, soattl, now); + adns__query_fail(qu, adns_s_nodata); + return; + } + + /* Now what ? No relevant answers, no SOA, and at least some NS's. + * Looks like a referral. Just one last chance ... if we came across + * a CNAME in this datagram then we should probably do our own CNAME + * lookup now in the hope that we won't get a referral again. + */ + if (cname_here) + goto x_restartquery; + + /* Bloody hell, I thought we asked for recursion ? */ + if (!flg_ra) { + adns__diag(ads, serv, qu, + "server is not willing to do recursive lookups for us"); + adns__query_fail(qu, adns_s_norecurse); + } else { + if (!flg_rd) + adns__diag(ads, serv, qu, + "server thinks we didn't ask for recursive lookup"); + else + adns__debug(ads, serv, qu, + "server claims to do recursion, but gave us a referral"); + adns__query_fail(qu, adns_s_invalidresponse); + } + return; + } + + /* Now, we have some RRs which we wanted. */ + + qu->answer->rrs.untyped = + adns__alloc_interim(qu, qu->typei->rrsz * wantedrrs); + if (!qu->answer->rrs.untyped) { + adns__query_fail(qu, adns_s_nomemory); + return; + } + + typei = qu->typei; + cbyte = anstart; + rrsdata = qu->answer->rrs.bytes; + + pai.ads = qu->ads; + pai.qu = qu; + pai.serv = serv; + pai.dgram = dgram; + pai.dglen = dglen; + pai.nsstart = nsstart; + pai.nscount = nscount; + pai.arcount = arcount; + pai.now = now; + + for (rri = 0, nrrs = 0; rri < ancount; rri++) { + st = adns__findrr(qu, serv, dgram, dglen, &cbyte, + &rrtype, &rrclass, &ttl, &rdlength, + &rdstart, &ownermatched); + assert(!st); + assert(rrtype != -1); + if (rrclass != DNS_CLASS_IN || + rrtype != (qu->typei->type & adns__rrt_typemask) || + !ownermatched) + continue; + adns__update_expires(qu, ttl, now); + st = typei->parse(&pai, rdstart, rdstart + rdlength, + rrsdata + nrrs * typei->rrsz); + if (st) { + adns__query_fail(qu, st); + return; + } + if (rdstart == -1) + goto x_truncated; + nrrs++; + } + assert(nrrs == wantedrrs); + qu->answer->nrrs = nrrs; + + /* This may have generated some child queries ... */ + if (qu->children.head) { + qu->state = query_childw; + LIST_LINK_TAIL(ads->childw, qu); + return; + } + adns__query_done(qu); + return; + + x_truncated: + + if (!flg_tc) { + adns__diag(ads, serv, qu, + "server sent datagram which points outside itself"); + adns__query_fail(qu, adns_s_invalidresponse); + return; + } + qu->flags |= adns_qf_usevc; + + x_restartquery: + if (qu->cname_dgram) { + st = adns__mkquery_frdgram(qu->ads, &qu->vb, &qu->id, + qu->cname_dgram, + qu->cname_dglen, + qu->cname_begin, + qu->typei->type, qu->flags); + if (st) { + adns__query_fail(qu, st); + return; + } + + newquery = realloc(qu->query_dgram, qu->vb.used); + if (!newquery) { + adns__query_fail(qu, adns_s_nomemory); + return; + } + + qu->query_dgram = newquery; + qu->query_dglen = qu->vb.used; + memcpy(newquery, qu->vb.buf, qu->vb.used); + } + + if (qu->state == query_tcpw) + qu->state = query_tosend; + qu->retries = 0; + adns__reset_preserved(qu); + adns__query_send(qu, now); +} diff --git a/adns/setup.c b/adns/setup.c new file mode 100644 index 0000000..f6e31b6 --- /dev/null +++ b/adns/setup.c @@ -0,0 +1,825 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * setup.c + * - configuration file parsing + * - management of global state + */ +/* + * This file is + * Copyright (C) 1997-1999 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "internal.h" + +static void readconfig(adns_state ads, const char *filename, + int warnmissing); + +static void addserver(adns_state ads, struct in_addr addr) +{ + int i; + struct server *ss; + + for (i = 0; i < ads->nservers; i++) { + if (ads->servers[i].addr.s_addr == addr.s_addr) { + adns__debug(ads, -1, 0, + "duplicate nameserver %s ignored", + inet_ntoa(addr)); + return; + } + } + + if (ads->nservers >= MAXSERVERS) { + adns__diag(ads, -1, 0, "too many nameservers, ignoring %s", + inet_ntoa(addr)); + return; + } + + ss = ads->servers + ads->nservers; + ss->addr = addr; + ads->nservers++; +} + +static void freesearchlist(adns_state ads) +{ + if (ads->nsearchlist) + free(*ads->searchlist); + free(ads->searchlist); +} + +static void saveerr(adns_state ads, int en) +{ + if (!ads->configerrno) + ads->configerrno = en; +} + +static void configparseerr(adns_state ads, const char *fn, int lno, + const char *fmt, ...) +{ + va_list al; + + saveerr(ads, EINVAL); + if (!ads->diagfile || (ads->iflags & adns_if_noerrprint)) + return; + + if (lno == -1) + fprintf(ads->diagfile, "adns: %s: ", fn); + else + fprintf(ads->diagfile, "adns: %s:%d: ", fn, lno); + va_start(al, fmt); + vfprintf(ads->diagfile, fmt, al); + va_end(al); + fputc('\n', ads->diagfile); +} + +static int nextword(const char **bufp_io, const char **word_r, int *l_r) +{ + const char *p, *q; + + p = *bufp_io; + while (ctype_whitespace(*p)) + p++; + if (!*p) + return 0; + + q = p; + while (*q && !ctype_whitespace(*q)) + q++; + + *l_r = q - p; + *word_r = p; + *bufp_io = q; + + return 1; +} + +static void ccf_nameserver(adns_state ads, const char *fn, int lno, + const char *buf) +{ + struct in_addr ia; + + if (!inet_aton(buf, &ia)) { + configparseerr(ads, fn, lno, + "invalid nameserver address `%s'", buf); + return; + } + adns__debug(ads, -1, 0, "using nameserver %s", inet_ntoa(ia)); + addserver(ads, ia); +} + +static void ccf_search(adns_state ads, const char *fn, int lno, + const char *buf) +{ + const char *bufp, *word; + char *newchars, **newptrs, **pp; + int count, tl, l; + + if (!buf) + return; + + bufp = buf; + count = 0; + tl = 0; + while (nextword(&bufp, &word, &l)) { + count++; + tl += l + 1; + } + + newptrs = malloc(sizeof(char *) * count); + if (!newptrs) { + saveerr(ads, errno); + return; + } + newchars = malloc(tl); + if (!newchars) { + saveerr(ads, errno); + free(newptrs); + return; + } + + bufp = buf; + pp = newptrs; + while (nextword(&bufp, &word, &l)) { + *pp++ = newchars; + memcpy(newchars, word, l); + newchars += l; + *newchars++ = 0; + } + + freesearchlist(ads); + ads->nsearchlist = count; + ads->searchlist = newptrs; +} + +static void ccf_sortlist(adns_state ads, const char *fn, int lno, + const char *buf) +{ + const char *word; + char tbuf[200], *slash, *ep; + struct in_addr base, mask; + int l; + unsigned long initial, baselocal; + + if (!buf) + return; + + ads->nsortlist = 0; + while (nextword(&buf, &word, &l)) { + if (ads->nsortlist >= MAXSORTLIST) { + adns__diag(ads, -1, 0, + "too many sortlist entries, ignoring %.*s onwards", + l, word); + return; + } + + if (l >= sizeof(tbuf)) { + configparseerr(ads, fn, lno, + "sortlist entry `%.*s' too long", l, + word); + continue; + } + + memcpy(tbuf, word, l); + tbuf[l] = 0; + slash = strchr(tbuf, '/'); + if (slash) + *slash++ = 0; + + if (!inet_aton(tbuf, &base)) { + configparseerr(ads, fn, lno, + "invalid address `%s' in sortlist", + tbuf); + continue; + } + + if (slash) { + if (strchr(slash, '.')) { + if (!inet_aton(slash, &mask)) { + configparseerr(ads, fn, lno, + "invalid mask `%s' in sortlist", + slash); + continue; + } + if (base.s_addr & ~mask.s_addr) { + configparseerr(ads, fn, lno, + "mask `%s' in sortlist overlaps address `%s'", + slash, tbuf); + continue; + } + } else { + initial = strtoul(slash, &ep, 10); + if (*ep || initial > 32) { + configparseerr(ads, fn, lno, + "mask length `%s' invalid", + slash); + continue; + } + mask.s_addr = + htonl((0x0ffffffffUL) << + (32 - initial)); + } + } else { + baselocal = ntohl(base.s_addr); + if (!baselocal & 0x080000000UL) /* class A */ + mask.s_addr = htonl(0x0ff000000UL); + else if ((baselocal & 0x0c0000000UL) == + 0x080000000UL) + mask.s_addr = htonl(0x0ffff0000UL); /* class B */ + else if ((baselocal & 0x0f0000000UL) == + 0x0e0000000UL) + mask.s_addr = htonl(0x0ff000000UL); /* class C */ + else { + configparseerr(ads, fn, lno, + "network address `%s' in sortlist is not in classed ranges," + " must specify mask explicitly", + tbuf); + continue; + } + } + + ads->sortlist[ads->nsortlist].base = base; + ads->sortlist[ads->nsortlist].mask = mask; + ads->nsortlist++; + } +} + +static void ccf_options(adns_state ads, const char *fn, int lno, + const char *buf) +{ + const char *word; + char *ep; + unsigned long v; + int l; + + if (!buf) + return; + + while (nextword(&buf, &word, &l)) { + if (l == 5 && !memcmp(word, "debug", 5)) { + ads->iflags |= adns_if_debug; + continue; + } + if (l >= 6 && !memcmp(word, "ndots:", 6)) { + v = strtoul(word + 6, &ep, 10); + if (l == 6 || ep != word + l || v > INT_MAX) { + configparseerr(ads, fn, lno, + "option `%.*s' malformed or has bad value", + l, word); + continue; + } + ads->searchndots = v; + continue; + } + if (l >= 12 && !memcmp(word, "adns_checkc:", 12)) { + if (!strcmp(word + 12, "none")) { + ads->iflags &= ~adns_if_checkc_freq; + ads->iflags |= adns_if_checkc_entex; + } else if (!strcmp(word + 12, "entex")) { + ads->iflags &= ~adns_if_checkc_freq; + ads->iflags |= adns_if_checkc_entex; + } else if (!strcmp(word + 12, "freq")) { + ads->iflags |= adns_if_checkc_freq; + } else { + configparseerr(ads, fn, lno, + "option adns_checkc has bad value `%s' " + "(must be none, entex or freq", + word + 12); + } + continue; + } + adns__diag(ads, -1, 0, "%s:%d: unknown option `%.*s'", fn, + lno, l, word); + } +} + +static void ccf_clearnss(adns_state ads, const char *fn, int lno, + const char *buf) +{ + ads->nservers = 0; +} + +static void ccf_include(adns_state ads, const char *fn, int lno, + const char *buf) +{ + if (!*buf) { + configparseerr(ads, fn, lno, + "`include' directive with no filename"); + return; + } + readconfig(ads, buf, 1); +} + +static const struct configcommandinfo { + const char *name; + void (*fn) (adns_state ads, const char *fn, int lno, + const char *buf); +} configcommandinfos[] = { + { + "nameserver", ccf_nameserver}, { + "domain", ccf_search}, { + "search", ccf_search}, { + "sortlist", ccf_sortlist}, { + "options", ccf_options}, { + "clearnameservers", ccf_clearnss}, { + "include", ccf_include}, { + 0} +}; + +typedef union { + FILE *file; + const char *text; +} getline_ctx; + +static int gl_file(adns_state ads, getline_ctx * src_io, + const char *filename, int lno, char *buf, int buflen) +{ + FILE *file = src_io->file; + int c, i; + char *p; + + p = buf; + buflen--; + i = 0; + + for (;;) { /* loop over chars */ + if (i == buflen) { + adns__diag(ads, -1, 0, + "%s:%d: line too long, ignored", + filename, lno); + goto x_badline; + } + c = getc(file); + if (!c) { + adns__diag(ads, -1, 0, + "%s:%d: line contains nul, ignored", + filename, lno); + goto x_badline; + } else if (c == '\n') { + break; + } else if (c == EOF) { + if (ferror(file)) { + saveerr(ads, errno); + adns__diag(ads, -1, 0, + "%s:%d: read error: %s", + filename, lno, strerror(errno)); + return -1; + } + if (!i) + return -1; + break; + } else { + *p++ = c; + i++; + } + } + + *p++ = 0; + return i; + + x_badline: + saveerr(ads, EINVAL); + while ((c = getc(file)) != EOF && c != '\n'); + return -2; +} + +static int gl_text(adns_state ads, getline_ctx * src_io, + const char *filename, int lno, char *buf, int buflen) +{ + const char *cp = src_io->text; + int l; + + if (!cp || !*cp) + return -1; + + if (*cp == ';' || *cp == '\n') + cp++; + l = strcspn(cp, ";\n"); + src_io->text = cp + l; + + if (l >= buflen) { + adns__diag(ads, -1, 0, "%s:%d: line too long, ignored", + filename, lno); + saveerr(ads, EINVAL); + return -2; + } + + memcpy(buf, cp, l); + buf[l] = 0; + return l; +} + +static void readconfiggeneric(adns_state ads, const char *filename, + int (*getline) (adns_state ads, + getline_ctx *, + const char *filename, + int lno, char *buf, + int buflen), + /* Returns >=0 for success, -1 for EOF or error + * (error will have been reported), or -2 for + * bad line was encountered, try again. + */ + getline_ctx gl_ctx) +{ + char linebuf[2000], *p, *q; + int lno, l, dirl; + const struct configcommandinfo *ccip; + + for (lno = 1; + (l = + getline(ads, &gl_ctx, filename, lno, linebuf, + sizeof(linebuf))) != -1; lno++) { + if (l == -2) + continue; + while (l > 0 && ctype_whitespace(linebuf[l - 1])) + l--; + linebuf[l] = 0; + p = linebuf; + while (ctype_whitespace(*p)) + p++; + if (*p == '#' || !*p) + continue; + q = p; + while (*q && !ctype_whitespace(*q)) + q++; + dirl = q - p; + for (ccip = configcommandinfos; + ccip->name && !(strlen(ccip->name) == dirl + && !memcmp(ccip->name, p, q - p)); + ccip++); + if (!ccip->name) { + adns__diag(ads, -1, 0, + "%s:%d: unknown configuration directive `%.*s'", + filename, lno, q - p, p); + continue; + } + while (ctype_whitespace(*q)) + q++; + ccip->fn(ads, filename, lno, q); + } +} + +static const char *instrum_getenv(adns_state ads, const char *envvar) +{ + const char *value; + + value = getenv(envvar); + if (!value) + adns__debug(ads, -1, 0, "environment variable %s not set", + envvar); + else + adns__debug(ads, -1, 0, + "environment variable %s set to `%s'", envvar, + value); + return value; +} + +static void readconfig(adns_state ads, const char *filename, + int warnmissing) +{ + getline_ctx gl_ctx; + + gl_ctx.file = fopen(filename, "r"); + if (!gl_ctx.file) { + if (errno == ENOENT) { + if (warnmissing) + adns__debug(ads, -1, 0, + "configuration file `%s' does not exist", + filename); + return; + } + saveerr(ads, errno); + adns__diag(ads, -1, 0, + "cannot open configuration file `%s': %s", + filename, strerror(errno)); + return; + } + + readconfiggeneric(ads, filename, gl_file, gl_ctx); + + fclose(gl_ctx.file); +} + +static void readconfigtext(adns_state ads, const char *text, + const char *showname) +{ + getline_ctx gl_ctx; + + gl_ctx.text = text; + readconfiggeneric(ads, showname, gl_text, gl_ctx); +} + +static void readconfigenv(adns_state ads, const char *envvar) +{ + const char *filename; + + if (ads->iflags & adns_if_noenv) { + adns__debug(ads, -1, 0, + "not checking environment variable `%s'", + envvar); + return; + } + filename = instrum_getenv(ads, envvar); + if (filename) + readconfig(ads, filename, 1); +} + +static void readconfigenvtext(adns_state ads, const char *envvar) +{ + const char *textdata; + + if (ads->iflags & adns_if_noenv) { + adns__debug(ads, -1, 0, + "not checking environment variable `%s'", + envvar); + return; + } + textdata = instrum_getenv(ads, envvar); + if (textdata) + readconfigtext(ads, textdata, envvar); +} + + +int adns__setnonblock(adns_state ads, int fd) +{ + int r; + + r = fcntl(fd, F_GETFL, 0); + if (r < 0) + return errno; + r |= O_NONBLOCK; + r = fcntl(fd, F_SETFL, r); + if (r < 0) + return errno; + return 0; +} + +static int init_begin(adns_state * ads_r, adns_initflags flags, + FILE * diagfile) +{ + adns_state ads; + + ads = malloc(sizeof(*ads)); + if (!ads) + return errno; + + ads->iflags = flags; + ads->diagfile = diagfile; + ads->configerrno = 0; + ALIST_INIT(ads->udpw); + ALIST_INIT(ads->tcpw); + ALIST_INIT(ads->childw); + ALIST_INIT(ads->output); + ads->forallnext = 0; + ads->nextid = 0x311f; + ads->udpsocket = ads->tcpsocket = -1; + adns__vbuf_init(&ads->tcpsend); + adns__vbuf_init(&ads->tcprecv); + ads->tcprecv_skip = 0; + ads->nservers = ads->nsortlist = ads->nsearchlist = + ads->tcpserver = 0; + ads->searchndots = 1; + ads->tcpstate = server_disconnected; + timerclear(&ads->tcptimeout); + ads->searchlist = 0; + + *ads_r = ads; + return 0; +} + +static int init_finish(adns_state ads) +{ + struct in_addr ia; + struct protoent *proto; + int r; + + if (!ads->nservers) { + if (ads->diagfile && ads->iflags & adns_if_debug) + fprintf(ads->diagfile, + "adns: no nameservers, using localhost\n"); + ia.s_addr = htonl(INADDR_LOOPBACK); + addserver(ads, ia); + } + + proto = getprotobyname("udp"); + if (!proto) { + r = ENOPROTOOPT; + goto x_free; + } + ads->udpsocket = socket(AF_INET, SOCK_DGRAM, proto->p_proto); + if (ads->udpsocket < 0) { + r = errno; + goto x_free; + } + + r = adns__setnonblock(ads, ads->udpsocket); + if (r) { + r = errno; + goto x_closeudp; + } + + return 0; + + x_closeudp: + close(ads->udpsocket); + x_free: + free(ads); + return r; +} + +static void init_abort(adns_state ads) +{ + if (ads->nsearchlist) { + free(ads->searchlist[0]); + free(ads->searchlist); + } + free(ads); +} + +int adns_init(adns_state * ads_r, adns_initflags flags, FILE * diagfile) +{ + adns_state ads; + const char *res_options, *adns_res_options; + int r; + + r = init_begin(&ads, flags, diagfile ? diagfile : stderr); + if (r) + return r; + + res_options = instrum_getenv(ads, "RES_OPTIONS"); + adns_res_options = instrum_getenv(ads, "ADNS_RES_OPTIONS"); + ccf_options(ads, "RES_OPTIONS", -1, res_options); + ccf_options(ads, "ADNS_RES_OPTIONS", -1, adns_res_options); + + readconfig(ads, "/etc/resolv.conf", 1); + readconfig(ads, "/etc/resolv-adns.conf", 0); + readconfigenv(ads, "RES_CONF"); + readconfigenv(ads, "ADNS_RES_CONF"); + + readconfigenvtext(ads, "RES_CONF_TEXT"); + readconfigenvtext(ads, "ADNS_RES_CONF_TEXT"); + + ccf_options(ads, "RES_OPTIONS", -1, res_options); + ccf_options(ads, "ADNS_RES_OPTIONS", -1, adns_res_options); + + ccf_search(ads, "LOCALDOMAIN", -1, + instrum_getenv(ads, "LOCALDOMAIN")); + ccf_search(ads, "ADNS_LOCALDOMAIN", -1, + instrum_getenv(ads, "ADNS_LOCALDOMAIN")); + + if (ads->configerrno && ads->configerrno != EINVAL) { + r = ads->configerrno; + init_abort(ads); + return r; + } + + r = init_finish(ads); + if (r) + return r; + + adns__consistency(ads, 0, cc_entex); + *ads_r = ads; + return 0; +} + +int adns_init_strcfg(adns_state * ads_r, adns_initflags flags, + FILE * diagfile, const char *configtext) +{ + adns_state ads; + int r; + + r = init_begin(&ads, flags, diagfile); + if (r) + return r; + + readconfigtext(ads, configtext, ""); + if (ads->configerrno) { + r = ads->configerrno; + init_abort(ads); + return r; + } + + r = init_finish(ads); + if (r) + return r; + adns__consistency(ads, 0, cc_entex); + *ads_r = ads; + return 0; +} + + +void adns_finish(adns_state ads) +{ + adns__consistency(ads, 0, cc_entex); + for (;;) { + if (ads->udpw.head) + adns_cancel(ads->udpw.head); + else if (ads->tcpw.head) + adns_cancel(ads->tcpw.head); + else if (ads->childw.head) + adns_cancel(ads->childw.head); + else if (ads->output.head) + adns_cancel(ads->output.head); + else + break; + } + close(ads->udpsocket); + if (ads->tcpsocket >= 0) + close(ads->tcpsocket); + adns__vbuf_free(&ads->tcpsend); + adns__vbuf_free(&ads->tcprecv); + freesearchlist(ads); + free(ads); +} + +void adns_forallqueries_begin(adns_state ads) +{ + adns__consistency(ads, 0, cc_entex); + ads->forallnext = + ads->udpw.head ? ads->udpw.head : + ads->tcpw.head ? ads->tcpw.head : + ads->childw.head ? ads->childw.head : ads->output.head; +} + +adns_query adns_forallqueries_next(adns_state ads, void **context_r) +{ + adns_query qu, nqu; + + adns__consistency(ads, 0, cc_entex); + nqu = ads->forallnext; + for (;;) { + qu = nqu; + if (!qu) + return 0; + if (qu->next) { + nqu = qu->next; + } else if (qu == ads->udpw.tail) { + nqu = + ads->tcpw.head ? ads->tcpw.head : + ads->childw.head ? ads->childw.head : + ads->output.head; + } else if (qu == ads->tcpw.tail) { + nqu = + ads->childw.head ? ads->childw.head : + ads->output.head; + } else if (qu == ads->childw.tail) { + nqu = ads->output.head; + } else { + nqu = 0; + } + if (!qu->parent) + break; + } + ads->forallnext = nqu; + if (context_r) + *context_r = qu->ctx.ext; + return qu; +} diff --git a/adns/transmit.c b/adns/transmit.c new file mode 100644 index 0000000..5500abb --- /dev/null +++ b/adns/transmit.c @@ -0,0 +1,330 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * transmit.c + * - construct queries + * - send queries + */ +/* + * This file is + * Copyright (C) 1997-2000 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include + +#include +#include + +#include "internal.h" +#include "tvarith.h" + +#define MKQUERY_START(vb) (rqp= (vb)->buf+(vb)->used) +#define MKQUERY_ADDB(b) *rqp++= (b) +#define MKQUERY_ADDW(w) (MKQUERY_ADDB(((w)>>8)&0x0ff), MKQUERY_ADDB((w)&0x0ff)) +#define MKQUERY_STOP(vb) ((vb)->used= rqp-(vb)->buf) + +static adns_status mkquery_header(adns_state ads, vbuf * vb, int *id_r, + int qdlen) +{ + int id; + byte *rqp; + + if (!adns__vbuf_ensure(vb, DNS_HDRSIZE + qdlen + 4)) + return adns_s_nomemory; + + vb->used = 0; + MKQUERY_START(vb); + + *id_r = id = (ads->nextid++) & 0x0ffff; + MKQUERY_ADDW(id); + MKQUERY_ADDB(0x01); /* QR=Q(0), OPCODE=QUERY(0000), !AA, !TC, RD */ + MKQUERY_ADDB(0x00); /* !RA, Z=000, RCODE=NOERROR(0000) */ + MKQUERY_ADDW(1); /* QDCOUNT=1 */ + MKQUERY_ADDW(0); /* ANCOUNT=0 */ + MKQUERY_ADDW(0); /* NSCOUNT=0 */ + MKQUERY_ADDW(0); /* ARCOUNT=0 */ + + MKQUERY_STOP(vb); + + return adns_s_ok; +} + +static adns_status mkquery_footer(vbuf * vb, adns_rrtype type) +{ + byte *rqp; + + MKQUERY_START(vb); + MKQUERY_ADDW(type & adns__rrt_typemask); /* QTYPE */ + MKQUERY_ADDW(DNS_CLASS_IN); /* QCLASS=IN */ + MKQUERY_STOP(vb); + assert(vb->used <= vb->avail); + + return adns_s_ok; +} + +adns_status adns__mkquery(adns_state ads, vbuf * vb, int *id_r, + const char *owner, int ol, + const typeinfo * typei, adns_queryflags flags) +{ + int ll, c, nbytes; + byte label[255], *rqp; + const char *p, *pe; + adns_status st; + + st = mkquery_header(ads, vb, id_r, ol + 2); + if (st) + return st; + + MKQUERY_START(vb); + + p = owner; + pe = owner + ol; + nbytes = 0; + while (p != pe) { + ll = 0; + while (p != pe && (c = *p++) != '.') { + if (c == '\\') { + if (!(flags & adns_qf_quoteok_query)) + return adns_s_querydomaininvalid; + if (ctype_digit(p[0])) { + if (ctype_digit(p[1]) + && ctype_digit(p[2])) { + c = (p[0] - '0') * 100 + + (p[1] - '0') * 10 + + (p[2] - '0'); + p += 3; + if (c >= 256) + return + adns_s_querydomaininvalid; + } else { + return + adns_s_querydomaininvalid; + } + } else if (!(c = *p++)) { + return adns_s_querydomaininvalid; + } + } + if (!(flags & adns_qf_quoteok_query)) { + if (c == '-') { + if (!ll) + return + adns_s_querydomaininvalid; + } else if (!ctype_alpha(c) + && !ctype_digit(c)) { + return adns_s_querydomaininvalid; + } + } + if (ll == sizeof(label)) + return adns_s_querydomaininvalid; + label[ll++] = c; + } + if (!ll) + return adns_s_querydomaininvalid; + if (ll > DNS_MAXLABEL) + return adns_s_querydomaintoolong; + nbytes += ll + 1; + if (nbytes >= DNS_MAXDOMAIN) + return adns_s_querydomaintoolong; + MKQUERY_ADDB(ll); + memcpy(rqp, label, ll); + rqp += ll; + } + MKQUERY_ADDB(0); + + MKQUERY_STOP(vb); + + st = mkquery_footer(vb, typei->type); + + return adns_s_ok; +} + +adns_status adns__mkquery_frdgram(adns_state ads, vbuf * vb, int *id_r, + const byte * qd_dgram, int qd_dglen, + int qd_begin, adns_rrtype type, + adns_queryflags flags) +{ + byte *rqp; + findlabel_state fls; + int lablen, labstart; + adns_status st; + + st = mkquery_header(ads, vb, id_r, qd_dglen); + if (st) + return st; + + MKQUERY_START(vb); + + adns__findlabel_start(&fls, ads, -1, 0, qd_dgram, qd_dglen, + qd_dglen, qd_begin, 0); + for (;;) { + st = adns__findlabel_next(&fls, &lablen, &labstart); + assert(!st); + if (!lablen) + break; + assert(lablen < 255); + MKQUERY_ADDB(lablen); + memcpy(rqp, qd_dgram + labstart, lablen); + rqp += lablen; + } + MKQUERY_ADDB(0); + + MKQUERY_STOP(vb); + + st = mkquery_footer(vb, type); + + return adns_s_ok; +} + +void adns__querysend_tcp(adns_query qu, struct timeval now) +{ + byte length[2]; + struct iovec iov[2]; + int wr, r; + adns_state ads; + + if (qu->ads->tcpstate != server_ok) + return; + + assert(qu->state == query_tcpw); + + length[0] = (qu->query_dglen & 0x0ff00U) >> 8; + length[1] = (qu->query_dglen & 0x0ff); + + ads = qu->ads; + if (!adns__vbuf_ensure + (&ads->tcpsend, ads->tcpsend.used + qu->query_dglen + 2)) + return; + + qu->retries++; + + /* Reset idle timeout. */ + ads->tcptimeout.tv_sec = ads->tcptimeout.tv_usec = 0; + + if (ads->tcpsend.used) { + wr = 0; + } else { + iov[0].iov_base = length; + iov[0].iov_len = 2; + iov[1].iov_base = qu->query_dgram; + iov[1].iov_len = qu->query_dglen; + adns__sigpipe_protect(qu->ads); + wr = writev(qu->ads->tcpsocket, iov, 2); + adns__sigpipe_unprotect(qu->ads); + if (wr < 0) { + if (! + (errno == EAGAIN || errno == EINTR + || errno == ENOSPC || errno == ENOBUFS + || errno == ENOMEM)) { + adns__tcp_broken(ads, "write", + strerror(errno)); + return; + } + wr = 0; + } + } + + if (wr < 2) { + r = adns__vbuf_append(&ads->tcpsend, length, 2 - wr); + assert(r); + wr = 0; + } else { + wr -= 2; + } + if (wr < qu->query_dglen) { + r = adns__vbuf_append(&ads->tcpsend, qu->query_dgram + wr, + qu->query_dglen - wr); + assert(r); + } +} + +static void query_usetcp(adns_query qu, struct timeval now) +{ + qu->state = query_tcpw; + qu->timeout = now; + timevaladd(&qu->timeout, TCPWAITMS); + LIST_LINK_TAIL(qu->ads->tcpw, qu); + adns__querysend_tcp(qu, now); + adns__tcp_tryconnect(qu->ads, now); +} + +void adns__query_send(adns_query qu, struct timeval now) +{ + struct sockaddr_in servaddr; + int serv, r; + adns_state ads; + + assert(qu->state == query_tosend); + if ((qu->flags & adns_qf_usevc) || (qu->query_dglen > DNS_MAXUDP)) { + query_usetcp(qu, now); + return; + } + + if (qu->retries >= UDPMAXRETRIES) { + adns__query_fail(qu, adns_s_timeout); + return; + } + + serv = qu->udpnextserver; + memset(&servaddr, 0, sizeof(servaddr)); + + ads = qu->ads; + servaddr.sin_family = AF_INET; + servaddr.sin_addr = ads->servers[serv].addr; + servaddr.sin_port = htons(DNS_PORT); + + r = sendto(ads->udpsocket, qu->query_dgram, qu->query_dglen, 0, + (const struct sockaddr *) &servaddr, sizeof(servaddr)); + if (r < 0 && errno == EMSGSIZE) { + qu->retries = 0; + query_usetcp(qu, now); + return; + } + if (r < 0 && errno != EAGAIN) + adns__warn(ads, serv, 0, "sendto failed: %s", + strerror(errno)); + + qu->timeout = now; + timevaladd(&qu->timeout, UDPRETRYMS); + qu->udpsent |= (1 << serv); + qu->udpnextserver = (serv + 1) % ads->nservers; + qu->retries++; + LIST_LINK_TAIL(ads->udpw, qu); +} diff --git a/adns/tvarith.h b/adns/tvarith.h new file mode 100644 index 0000000..15de090 --- /dev/null +++ b/adns/tvarith.h @@ -0,0 +1,67 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * tvarith.h + * - static inline functions for doing arithmetic on timevals + */ +/* + * This file is + * Copyright (C) 1997-1999 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef ADNS_TVARITH_H_INCLUDED +#define ADNS_TVARITH_H_INCLUDED + +static inline void timevaladd(struct timeval *tv_io, long ms) +{ + struct timeval tmp; + assert(ms >= 0); + tmp = *tv_io; + tmp.tv_usec += (ms % 1000) * 1000; + tmp.tv_sec += ms / 1000; + if (tmp.tv_usec >= 1000000) { + tmp.tv_sec++; + tmp.tv_usec -= 1000000; + } + *tv_io = tmp; +} + +#endif diff --git a/adns/types.c b/adns/types.c new file mode 100644 index 0000000..d6e3f4b --- /dev/null +++ b/adns/types.c @@ -0,0 +1,1281 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ +/* + * types.c + * - RR-type-specific code, and the machinery to call it + */ +/* + * This file is + * Copyright (C) 1997-1999 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-2000 Ian Jackson + * Copyright (C) 1999-2000 Tony Finch + * + * 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include + +#include +#include +#include +#include + +#include "internal.h" + +#define R_NOMEM return adns_s_nomemory +#define CSP_ADDSTR(s) do { if (!adns__vbuf_appendstr(vb,(s))) R_NOMEM; } while (0) + +/* + * order of sections: + * + * _string (pap) + * _textdata, _qstring (csp) + * _str (mf,cs) + * _intstr (mf,csp,cs) + * _manyistr (mf,cs) + * _txt (pa) + * _inaddr (pa,dip,di) + * _addr (pa,di,csp,cs) + * _domain (pap) + * _host_raw (pa) + * _hostaddr (pap,pa,dip,di,mfp,mf,csp,cs +pap_findaddrs) + * _mx_raw (pa,di) + * _mx (pa,di) + * _inthostaddr (mf,cs) + * _ptr (pa) + * _strpair (mf,cs) + * _intstrpair (mf,cs) + * _hinfo (pa) + * _mailbox (pap +pap_mailbox822) + * _rp (pa) + * _soa (pa,mf,cs) + * _flat (mf) + * + * within each section: + * pap_* + * pa_* + * dip_* + * di_* + * mfp_* + * mf_* + * csp_* + * cs_* + */ + +/* + * _qstring (pap,csp) + */ + +static adns_status pap_qstring(const parseinfo * pai, int *cbyte_io, + int max, int *len_r, char **str_r) +{ + /* Neither len_r nor str_r may be null. + * End of datagram (overrun) is indicated by returning adns_s_invaliddata; + */ + const byte *dgram = pai->dgram; + int l, cbyte; + char *str; + + cbyte = *cbyte_io; + + if (cbyte >= max) + return adns_s_invaliddata; + GET_B(cbyte, l); + if (cbyte + l > max) + return adns_s_invaliddata; + + str = adns__alloc_interim(pai->qu, l + 1); + if (!str) + R_NOMEM; + + str[l] = 0; + memcpy(str, dgram + cbyte, l); + + *len_r = l; + *str_r = str; + *cbyte_io = cbyte + l; + + return adns_s_ok; +} + +static adns_status csp_qstring(vbuf * vb, const char *dp, int len) +{ + unsigned char ch; + char buf[10]; + int cn; + + CSP_ADDSTR("\""); + for (cn = 0; cn < len; cn++) { + ch = *dp++; + if (ch == '\\') { + CSP_ADDSTR("\\\\"); + } else if (ch == '"') { + CSP_ADDSTR("\\\""); + } else if (ch >= 32 && ch <= 126) { + if (!adns__vbuf_append(vb, &ch, 1)) + R_NOMEM; + } else { + sprintf(buf, "\\x%02x", ch); + CSP_ADDSTR(buf); + } + } + CSP_ADDSTR("\""); + + return adns_s_ok; +} + +/* + * _str (mf) + */ + +static void mf_str(adns_query qu, void *datap) +{ + char **rrp = datap; + + adns__makefinal_str(qu, rrp); +} + +/* + * _intstr (mf) + */ + +static void mf_intstr(adns_query qu, void *datap) +{ + adns_rr_intstr *rrp = datap; + + adns__makefinal_str(qu, &rrp->str); +} + +/* + * _manyistr (mf) + */ + +static void mf_manyistr(adns_query qu, void *datap) +{ + adns_rr_intstr **rrp = datap; + adns_rr_intstr *te, *table; + void *tablev; + int tc; + + for (tc = 0, te = *rrp; te->i >= 0; te++, tc++); + tablev = *rrp; + adns__makefinal_block(qu, &tablev, sizeof(*te) * (tc + 1)); + *rrp = table = tablev; + for (te = *rrp; te->i >= 0; te++) + adns__makefinal_str(qu, &te->str); +} + +/* + * _txt (pa,cs) + */ + +static adns_status pa_txt(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + adns_rr_intstr **rrp = datap, *table, *te; + const byte *dgram = pai->dgram; + int ti, tc, l, startbyte; + adns_status st; + + startbyte = cbyte; + if (cbyte >= max) + return adns_s_invaliddata; + tc = 0; + while (cbyte < max) { + GET_B(cbyte, l); + cbyte += l; + tc++; + } + if (cbyte != max || !tc) + return adns_s_invaliddata; + + table = adns__alloc_interim(pai->qu, sizeof(*table) * (tc + 1)); + if (!table) + R_NOMEM; + + for (cbyte = startbyte, ti = 0, te = table; ti < tc; ti++, te++) { + st = pap_qstring(pai, &cbyte, max, &te->i, &te->str); + if (st) + return st; + } + assert(cbyte == max); + + te->i = -1; + te->str = 0; + + *rrp = table; + return adns_s_ok; +} + +static adns_status cs_txt(vbuf * vb, const void *datap) +{ + const adns_rr_intstr *const *rrp = datap; + const adns_rr_intstr *current; + adns_status st; + int spc; + + for (current = *rrp, spc = 0; current->i >= 0; current++, spc = 1) { + if (spc) + CSP_ADDSTR(" "); + st = csp_qstring(vb, current->str, current->i); + if (st) + return st; + } + return adns_s_ok; +} + +/* + * _hinfo (cs) + */ + +static adns_status cs_hinfo(vbuf * vb, const void *datap) +{ + const adns_rr_intstrpair *rrp = datap; + adns_status st; + + st = csp_qstring(vb, rrp->array[0].str, rrp->array[0].i); + if (st) + return st; + CSP_ADDSTR(" "); + st = csp_qstring(vb, rrp->array[1].str, rrp->array[1].i); + if (st) + return st; + return adns_s_ok; +} + +/* + * _inaddr (pa,dip,di) + */ + +static adns_status pa_inaddr(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + struct in_addr *storeto = datap; + + if (max - cbyte != 4) + return adns_s_invaliddata; + memcpy(storeto, pai->dgram + cbyte, 4); + return adns_s_ok; +} + +static int search_sortlist(adns_state ads, struct in_addr ad) +{ + const struct sortlist *slp; + int i; + + for (i = 0, slp = ads->sortlist; + i < ads->nsortlist + && !((ad.s_addr & slp->mask.s_addr) == slp->base.s_addr); + i++, slp++); + return i; +} + +static int dip_inaddr(adns_state ads, struct in_addr a, struct in_addr b) +{ + int ai, bi; + + if (!ads->nsortlist) + return 0; + + ai = search_sortlist(ads, a); + bi = search_sortlist(ads, b); + return bi < ai; +} + +static int di_inaddr(adns_state ads, const void *datap_a, + const void *datap_b) +{ + const struct in_addr *ap = datap_a, *bp = datap_b; + + return dip_inaddr(ads, *ap, *bp); +} + +static adns_status cs_inaddr(vbuf * vb, const void *datap) +{ + const struct in_addr *rrp = datap, rr = *rrp; + const char *ia; + + ia = inet_ntoa(rr); + assert(ia); + CSP_ADDSTR(ia); + return adns_s_ok; +} + +/* + * _addr (pa,di,csp,cs) + */ + +static adns_status pa_addr(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + adns_rr_addr *storeto = datap; + const byte *dgram = pai->dgram; + + if (max - cbyte != 4) + return adns_s_invaliddata; + storeto->len = sizeof(storeto->addr.inet); + memset(&storeto->addr, 0, sizeof(storeto->addr.inet)); + storeto->addr.inet.sin_family = AF_INET; + memcpy(&storeto->addr.inet.sin_addr, dgram + cbyte, 4); + return adns_s_ok; +} + +static int di_addr(adns_state ads, const void *datap_a, + const void *datap_b) +{ + const adns_rr_addr *ap = datap_a, *bp = datap_b; + + assert(ap->addr.sa.sa_family == AF_INET); + return dip_inaddr(ads, ap->addr.inet.sin_addr, + bp->addr.inet.sin_addr); +} + +static int div_addr(void *context, const void *datap_a, + const void *datap_b) +{ + const adns_state ads = context; + + return di_addr(ads, datap_a, datap_b); +} + +static adns_status csp_addr(vbuf * vb, const adns_rr_addr * rrp) +{ + const char *ia; + static char buf[30]; + + switch (rrp->addr.inet.sin_family) { + case AF_INET: + CSP_ADDSTR("INET "); + ia = inet_ntoa(rrp->addr.inet.sin_addr); + assert(ia); + CSP_ADDSTR(ia); + break; + default: + sprintf(buf, "AF=%u", rrp->addr.sa.sa_family); + CSP_ADDSTR(buf); + break; + } + return adns_s_ok; +} + +static adns_status cs_addr(vbuf * vb, const void *datap) +{ + const adns_rr_addr *rrp = datap; + + return csp_addr(vb, rrp); +} + +/* + * _domain (pap,csp,cs) + * _dom_raw (pa) + */ + +static adns_status pap_domain(const parseinfo * pai, int *cbyte_io, + int max, char **domain_r, + parsedomain_flags flags) +{ + adns_status st; + char *dm; + + st = adns__parse_domain(pai->qu->ads, pai->serv, pai->qu, + &pai->qu->vb, flags, pai->dgram, + pai->dglen, cbyte_io, max); + if (st) + return st; + if (!pai->qu->vb.used) + return adns_s_invaliddata; + + dm = adns__alloc_interim(pai->qu, pai->qu->vb.used + 1); + if (!dm) + R_NOMEM; + + dm[pai->qu->vb.used] = 0; + memcpy(dm, pai->qu->vb.buf, pai->qu->vb.used); + + *domain_r = dm; + return adns_s_ok; +} + +static adns_status csp_domain(vbuf * vb, const char *domain) +{ + CSP_ADDSTR(domain); + if (!*domain) + CSP_ADDSTR("."); + return adns_s_ok; +} + +static adns_status cs_domain(vbuf * vb, const void *datap) +{ + const char *const *domainp = datap; + return csp_domain(vb, *domainp); +} + +static adns_status pa_dom_raw(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + char **rrp = datap; + adns_status st; + + st = pap_domain(pai, &cbyte, max, rrp, pdf_quoteok); + if (st) + return st; + + if (cbyte != max) + return adns_s_invaliddata; + return adns_s_ok; +} + +/* + * _host_raw (pa) + */ + +static adns_status pa_host_raw(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + char **rrp = datap; + adns_status st; + + st = pap_domain(pai, &cbyte, max, rrp, + pai->qu-> + flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); + if (st) + return st; + + if (cbyte != max) + return adns_s_invaliddata; + return adns_s_ok; +} + +/* + * _hostaddr (pap,pa,dip,di,mfp,mf,csp,cs +icb_hostaddr, pap_findaddrs) + */ + +static adns_status pap_findaddrs(const parseinfo * pai, + adns_rr_hostaddr * ha, int *cbyte_io, + int count, int dmstart) +{ + int rri, naddrs; + int type, class, rdlen, rdstart, ownermatched; + unsigned long ttl; + adns_status st; + + for (rri = 0, naddrs = -1; rri < count; rri++) { + st = adns__findrr_anychk(pai->qu, pai->serv, pai->dgram, + pai->dglen, cbyte_io, &type, + &class, &ttl, &rdlen, &rdstart, + pai->dgram, pai->dglen, dmstart, + &ownermatched); + if (st) + return st; + if (!ownermatched || class != DNS_CLASS_IN + || type != adns_r_a) { + if (naddrs > 0) + break; + else + continue; + } + if (naddrs == -1) { + naddrs = 0; + } + if (!adns__vbuf_ensure + (&pai->qu->vb, (naddrs + 1) * sizeof(adns_rr_addr))) + R_NOMEM; + adns__update_expires(pai->qu, ttl, pai->now); + st = pa_addr(pai, rdstart, rdstart + rdlen, + pai->qu->vb.buf + + naddrs * sizeof(adns_rr_addr)); + if (st) + return st; + naddrs++; + } + if (naddrs >= 0) { + ha->addrs = + adns__alloc_interim(pai->qu, + naddrs * sizeof(adns_rr_addr)); + if (!ha->addrs) + R_NOMEM; + memcpy(ha->addrs, pai->qu->vb.buf, + naddrs * sizeof(adns_rr_addr)); + ha->naddrs = naddrs; + ha->astatus = adns_s_ok; + + adns__isort(ha->addrs, naddrs, sizeof(adns_rr_addr), + pai->qu->vb.buf, div_addr, pai->ads); + } + return adns_s_ok; +} + +static void icb_hostaddr(adns_query parent, adns_query child) +{ + adns_answer *cans = child->answer; + adns_rr_hostaddr *rrp = child->ctx.info.hostaddr; + adns_state ads = parent->ads; + adns_status st; + + st = cans->status; + rrp->astatus = st; + rrp->naddrs = (st > 0 + && st <= adns_s_max_tempfail) ? -1 : cans->nrrs; + rrp->addrs = cans->rrs.addr; + adns__transfer_interim(child, parent, rrp->addrs, + rrp->naddrs * sizeof(adns_rr_addr)); + + if (parent->children.head) { + LIST_LINK_TAIL(ads->childw, parent); + } else { + adns__query_done(parent); + } +} + +static adns_status pap_hostaddr(const parseinfo * pai, int *cbyte_io, + int max, adns_rr_hostaddr * rrp) +{ + adns_status st; + int dmstart, cbyte; + qcontext ctx; + int id; + adns_query nqu; + adns_queryflags nflags; + + dmstart = cbyte = *cbyte_io; + st = pap_domain(pai, &cbyte, max, &rrp->host, + pai->qu-> + flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); + if (st) + return st; + *cbyte_io = cbyte; + + rrp->astatus = adns_s_ok; + rrp->naddrs = -1; + rrp->addrs = 0; + + cbyte = pai->nsstart; + + st = pap_findaddrs(pai, rrp, &cbyte, pai->nscount, dmstart); + if (st) + return st; + if (rrp->naddrs != -1) + return adns_s_ok; + + st = pap_findaddrs(pai, rrp, &cbyte, pai->arcount, dmstart); + if (st) + return st; + if (rrp->naddrs != -1) + return adns_s_ok; + + st = adns__mkquery_frdgram(pai->ads, &pai->qu->vb, &id, + pai->dgram, pai->dglen, dmstart, + adns_r_addr, adns_qf_quoteok_query); + if (st) + return st; + + ctx.ext = 0; + ctx.callback = icb_hostaddr; + ctx.info.hostaddr = rrp; + + nflags = adns_qf_quoteok_query; + if (!(pai->qu->flags & adns_qf_cname_loose)) + nflags |= adns_qf_cname_forbid; + + st = adns__internal_submit(pai->ads, &nqu, + adns__findtype(adns_r_addr), + &pai->qu->vb, id, nflags, pai->now, + &ctx); + if (st) + return st; + + nqu->parent = pai->qu; + LIST_LINK_TAIL_PART(pai->qu->children, nqu, siblings.); + + return adns_s_ok; +} + +static adns_status pa_hostaddr(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + adns_rr_hostaddr *rrp = datap; + adns_status st; + + st = pap_hostaddr(pai, &cbyte, max, rrp); + if (st) + return st; + if (cbyte != max) + return adns_s_invaliddata; + + return adns_s_ok; +} + +static int dip_hostaddr(adns_state ads, const adns_rr_hostaddr * ap, + const adns_rr_hostaddr * bp) +{ + if (ap->astatus != bp->astatus) + return ap->astatus; + if (ap->astatus) + return 0; + + assert(ap->addrs[0].addr.sa.sa_family == AF_INET); + assert(bp->addrs[0].addr.sa.sa_family == AF_INET); + return dip_inaddr(ads, + ap->addrs[0].addr.inet.sin_addr, + bp->addrs[0].addr.inet.sin_addr); +} + +static int di_hostaddr(adns_state ads, const void *datap_a, + const void *datap_b) +{ + const adns_rr_hostaddr *ap = datap_a, *bp = datap_b; + + return dip_hostaddr(ads, ap, bp); +} + +static void mfp_hostaddr(adns_query qu, adns_rr_hostaddr * rrp) +{ + void *tablev; + + adns__makefinal_str(qu, &rrp->host); + tablev = rrp->addrs; + adns__makefinal_block(qu, &tablev, + rrp->naddrs * sizeof(*rrp->addrs)); + rrp->addrs = tablev; +} + +static void mf_hostaddr(adns_query qu, void *datap) +{ + adns_rr_hostaddr *rrp = datap; + + mfp_hostaddr(qu, rrp); +} + +static adns_status csp_hostaddr(vbuf * vb, const adns_rr_hostaddr * rrp) +{ + const char *errstr; + adns_status st; + char buf[20]; + int i; + + st = csp_domain(vb, rrp->host); + if (st) + return st; + + CSP_ADDSTR(" "); + CSP_ADDSTR(adns_errtypeabbrev(rrp->astatus)); + + sprintf(buf, " %d ", rrp->astatus); + CSP_ADDSTR(buf); + + CSP_ADDSTR(adns_errabbrev(rrp->astatus)); + CSP_ADDSTR(" "); + + errstr = adns_strerror(rrp->astatus); + st = csp_qstring(vb, errstr, strlen(errstr)); + if (st) + return st; + + if (rrp->naddrs >= 0) { + CSP_ADDSTR(" ("); + for (i = 0; i < rrp->naddrs; i++) { + CSP_ADDSTR(" "); + st = csp_addr(vb, &rrp->addrs[i]); + } + CSP_ADDSTR(" )"); + } else { + CSP_ADDSTR(" ?"); + } + return adns_s_ok; +} + +static adns_status cs_hostaddr(vbuf * vb, const void *datap) +{ + const adns_rr_hostaddr *rrp = datap; + + return csp_hostaddr(vb, rrp); +} + +/* + * _mx_raw (pa,di) + */ + +static adns_status pa_mx_raw(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + const byte *dgram = pai->dgram; + adns_rr_intstr *rrp = datap; + adns_status st; + int pref; + + if (cbyte + 2 > max) + return adns_s_invaliddata; + GET_W(cbyte, pref); + rrp->i = pref; + st = pap_domain(pai, &cbyte, max, &rrp->str, + pai->qu-> + flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); + if (st) + return st; + + if (cbyte != max) + return adns_s_invaliddata; + return adns_s_ok; +} + +static int di_mx_raw(adns_state ads, const void *datap_a, + const void *datap_b) +{ + const adns_rr_intstr *ap = datap_a, *bp = datap_b; + + if (ap->i < bp->i) + return 0; + if (ap->i > bp->i) + return 1; + return 0; +} + +/* + * _mx (pa,di) + */ + +static adns_status pa_mx(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + const byte *dgram = pai->dgram; + adns_rr_inthostaddr *rrp = datap; + adns_status st; + int pref; + + if (cbyte + 2 > max) + return adns_s_invaliddata; + GET_W(cbyte, pref); + rrp->i = pref; + st = pap_hostaddr(pai, &cbyte, max, &rrp->ha); + if (st) + return st; + + if (cbyte != max) + return adns_s_invaliddata; + return adns_s_ok; +} + +static int di_mx(adns_state ads, const void *datap_a, const void *datap_b) +{ + const adns_rr_inthostaddr *ap = datap_a, *bp = datap_b; + + if (ap->i < bp->i) + return 0; + if (ap->i > bp->i) + return 1; + return dip_hostaddr(ads, &ap->ha, &bp->ha); +} + +/* + * _inthostaddr (mf,cs) + */ + +static void mf_inthostaddr(adns_query qu, void *datap) +{ + adns_rr_inthostaddr *rrp = datap; + + mfp_hostaddr(qu, &rrp->ha); +} + +static adns_status cs_inthostaddr(vbuf * vb, const void *datap) +{ + const adns_rr_inthostaddr *rrp = datap; + char buf[10]; + + sprintf(buf, "%u ", rrp->i); + CSP_ADDSTR(buf); + + return csp_hostaddr(vb, &rrp->ha); +} + +/* + * _inthost (cs) + */ + +static adns_status cs_inthost(vbuf * vb, const void *datap) +{ + const adns_rr_intstr *rrp = datap; + char buf[10]; + + sprintf(buf, "%u ", rrp->i); + CSP_ADDSTR(buf); + return csp_domain(vb, rrp->str); +} + +/* + * _ptr (pa, +icb_ptr) + */ + +static void icb_ptr(adns_query parent, adns_query child) +{ + adns_answer *cans = child->answer; + const adns_rr_addr *queried, *found; + adns_state ads = parent->ads; + int i; + + if (cans->status == adns_s_nxdomain + || cans->status == adns_s_nodata) { + adns__query_fail(parent, adns_s_inconsistent); + return; + } else if (cans->status) { + adns__query_fail(parent, cans->status); + return; + } + + queried = &parent->ctx.info.ptr_parent_addr; + for (i = 0, found = cans->rrs.addr; i < cans->nrrs; i++, found++) { + if (queried->len == found->len && + !memcmp(&queried->addr, &found->addr, queried->len)) { + if (!parent->children.head) { + adns__query_done(parent); + return; + } else { + LIST_LINK_TAIL(ads->childw, parent); + return; + } + } + } + + adns__query_fail(parent, adns_s_inconsistent); +} + +static adns_status pa_ptr(const parseinfo * pai, int dmstart, int max, + void *datap) +{ + static const char *(expectdomain[]) = { + DNS_INADDR_ARPA}; + + char **rrp = datap; + adns_status st; + adns_rr_addr *ap; + findlabel_state fls; + char *ep; + byte ipv[4]; + char labbuf[4]; + int cbyte, i, lablen, labstart, l, id; + adns_query nqu; + qcontext ctx; + + cbyte = dmstart; + st = pap_domain(pai, &cbyte, max, rrp, + pai->qu-> + flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); + if (st) + return st; + if (cbyte != max) + return adns_s_invaliddata; + + ap = &pai->qu->ctx.info.ptr_parent_addr; + if (!ap->len) { + adns__findlabel_start(&fls, pai->ads, -1, pai->qu, + pai->qu->query_dgram, + pai->qu->query_dglen, + pai->qu->query_dglen, DNS_HDRSIZE, + 0); + for (i = 0; i < 4; i++) { + st = adns__findlabel_next(&fls, &lablen, + &labstart); + assert(!st); + if (lablen <= 0 || lablen > 3) + return adns_s_querydomainwrong; + memcpy(labbuf, pai->qu->query_dgram + labstart, + lablen); + labbuf[lablen] = 0; + ipv[3 - i] = strtoul(labbuf, &ep, 10); + if (*ep) + return adns_s_querydomainwrong; + if (lablen > 1 + && pai->qu->query_dgram[labstart] == '0') + return adns_s_querydomainwrong; + } + for (i = 0; + i < sizeof(expectdomain) / sizeof(*expectdomain); + i++) { + st = adns__findlabel_next(&fls, &lablen, + &labstart); + assert(!st); + l = strlen(expectdomain[i]); + if (lablen != l + || memcmp(pai->qu->query_dgram + labstart, + expectdomain[i], l)) + return adns_s_querydomainwrong; + } + st = adns__findlabel_next(&fls, &lablen, 0); + assert(!st); + if (lablen) + return adns_s_querydomainwrong; + + ap->len = sizeof(struct sockaddr_in); + memset(&ap->addr, 0, sizeof(ap->addr.inet)); + ap->addr.inet.sin_family = AF_INET; + ap->addr.inet.sin_addr.s_addr = + htonl((ipv[0] << 24) | (ipv[1] << 16) | (ipv[2] << 8) | + (ipv[3])); + } + + st = adns__mkquery_frdgram(pai->ads, &pai->qu->vb, &id, + pai->dgram, pai->dglen, dmstart, + adns_r_addr, adns_qf_quoteok_query); + if (st) + return st; + + ctx.ext = 0; + ctx.callback = icb_ptr; + memset(&ctx.info, 0, sizeof(ctx.info)); + st = adns__internal_submit(pai->ads, &nqu, + adns__findtype(adns_r_addr), + &pai->qu->vb, id, adns_qf_quoteok_query, + pai->now, &ctx); + if (st) + return st; + + nqu->parent = pai->qu; + LIST_LINK_TAIL_PART(pai->qu->children, nqu, siblings.); + return adns_s_ok; +} + +/* + * _strpair (mf) + */ + +static void mf_strpair(adns_query qu, void *datap) +{ + adns_rr_strpair *rrp = datap; + + adns__makefinal_str(qu, &rrp->array[0]); + adns__makefinal_str(qu, &rrp->array[1]); +} + +/* + * _intstrpair (mf) + */ + +static void mf_intstrpair(adns_query qu, void *datap) +{ + adns_rr_intstrpair *rrp = datap; + + adns__makefinal_str(qu, &rrp->array[0].str); + adns__makefinal_str(qu, &rrp->array[1].str); +} + +/* + * _hinfo (pa) + */ + +static adns_status pa_hinfo(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + adns_rr_intstrpair *rrp = datap; + adns_status st; + int i; + + for (i = 0; i < 2; i++) { + st = pap_qstring(pai, &cbyte, max, &rrp->array[i].i, + &rrp->array[i].str); + if (st) + return st; + } + + if (cbyte != max) + return adns_s_invaliddata; + + return adns_s_ok; +} + +/* + * _mailbox (pap,cs) + */ + +static adns_status pap_mailbox822(const parseinfo * pai, int *cbyte_io, + int max, char **mb_r) +{ + int lablen, labstart, i, needquote, c, r, neednorm; + const unsigned char *p; + char *str; + findlabel_state fls; + adns_status st; + vbuf *vb; + + vb = &pai->qu->vb; + vb->used = 0; + adns__findlabel_start(&fls, pai->ads, + -1, pai->qu, + pai->dgram, pai->dglen, max, + *cbyte_io, cbyte_io); + st = adns__findlabel_next(&fls, &lablen, &labstart); + if (!lablen) { + adns__vbuf_appendstr(vb, "."); + goto x_ok; + } + + neednorm = 1; + for (i = 0, needquote = 0, p = pai->dgram + labstart; i < lablen; + i++) { + c = *p++; + if ((c & ~128) < 32 || (c & ~128) == 127) + return adns_s_invaliddata; + if (c == '.' && !neednorm) + neednorm = 1; + else if (c == ' ' || c >= 127 || ctype_822special(c)) + needquote++; + else + neednorm = 0; + } + + if (needquote || neednorm) { + r = adns__vbuf_ensure(vb, lablen + needquote + 4); + if (!r) + R_NOMEM; + adns__vbuf_appendq(vb, "\"", 1); + for (i = 0, needquote = 0, p = pai->dgram + labstart; + i < lablen; i++, p++) { + c = *p; + if (c == '"' || c == '\\') + adns__vbuf_appendq(vb, "\\", 1); + adns__vbuf_appendq(vb, p, 1); + } + adns__vbuf_appendq(vb, "\"", 1); + } else { + r = adns__vbuf_append(vb, pai->dgram + labstart, lablen); + if (!r) + R_NOMEM; + } + + r = adns__vbuf_appendstr(vb, "@"); + if (!r) + R_NOMEM; + + st = adns__parse_domain_more(&fls, pai->ads, pai->qu, vb, 0, + pai->dgram); + if (st) + return st; + + x_ok: + str = adns__alloc_interim(pai->qu, vb->used + 1); + if (!str) + R_NOMEM; + memcpy(str, vb->buf, vb->used); + str[vb->used] = 0; + *mb_r = str; + return adns_s_ok; +} + +static adns_status pap_mailbox(const parseinfo * pai, int *cbyte_io, + int max, char **mb_r) +{ + if (pai->qu->typei->type & adns__qtf_mail822) { + return pap_mailbox822(pai, cbyte_io, max, mb_r); + } else { + return pap_domain(pai, cbyte_io, max, mb_r, pdf_quoteok); + } +} + +static adns_status csp_mailbox(vbuf * vb, const char *mailbox) +{ + return csp_domain(vb, mailbox); +} + +/* + * _rp (pa,cs) + */ + +static adns_status pa_rp(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + adns_rr_strpair *rrp = datap; + adns_status st; + + st = pap_mailbox(pai, &cbyte, max, &rrp->array[0]); + if (st) + return st; + + st = pap_domain(pai, &cbyte, max, &rrp->array[1], pdf_quoteok); + if (st) + return st; + + if (cbyte != max) + return adns_s_invaliddata; + return adns_s_ok; +} + +static adns_status cs_rp(vbuf * vb, const void *datap) +{ + const adns_rr_strpair *rrp = datap; + adns_status st; + + st = csp_mailbox(vb, rrp->array[0]); + if (st) + return st; + CSP_ADDSTR(" "); + st = csp_domain(vb, rrp->array[1]); + if (st) + return st; + + return adns_s_ok; +} + +/* + * _soa (pa,mf,cs) + */ + +static adns_status pa_soa(const parseinfo * pai, int cbyte, int max, + void *datap) +{ + adns_rr_soa *rrp = datap; + const byte *dgram = pai->dgram; + adns_status st; + int msw, lsw, i; + + st = pap_domain(pai, &cbyte, max, &rrp->mname, + pai->qu-> + flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); + if (st) + return st; + + st = pap_mailbox(pai, &cbyte, max, &rrp->rname); + if (st) + return st; + + if (cbyte + 20 != max) + return adns_s_invaliddata; + + for (i = 0; i < 5; i++) { + GET_W(cbyte, msw); + GET_W(cbyte, lsw); + (&rrp->serial)[i] = (msw << 16) | lsw; + } + + return adns_s_ok; +} + +static void mf_soa(adns_query qu, void *datap) +{ + adns_rr_soa *rrp = datap; + + adns__makefinal_str(qu, &rrp->mname); + adns__makefinal_str(qu, &rrp->rname); +} + +static adns_status cs_soa(vbuf * vb, const void *datap) +{ + const adns_rr_soa *rrp = datap; + char buf[20]; + int i; + adns_status st; + + st = csp_domain(vb, rrp->mname); + if (st) + return st; + CSP_ADDSTR(" "); + st = csp_mailbox(vb, rrp->rname); + if (st) + return st; + + for (i = 0; i < 5; i++) { + sprintf(buf, " %lu", (&rrp->serial)[i]); + CSP_ADDSTR(buf); + } + + return adns_s_ok; +} + +/* + * _flat (mf) + */ + +static void mf_flat(adns_query qu, void *data) +{ +} + +/* + * Now the table. + */ + +#define TYPESZ_M(member) (sizeof(*((adns_answer*)0)->rrs.member)) + +#define DEEP_MEMB(memb) TYPESZ_M(memb), mf_##memb, cs_##memb +#define FLAT_MEMB(memb) TYPESZ_M(memb), mf_flat, cs_##memb + +#define DEEP_TYPE(code,rrt,fmt,memb,parser,comparer,printer) \ + { adns_r_##code, rrt, fmt, TYPESZ_M(memb), mf_##memb, printer, parser, comparer } +#define FLAT_TYPE(code,rrt,fmt,memb,parser,comparer,printer) \ + { adns_r_##code, rrt, fmt, TYPESZ_M(memb), mf_flat, printer, parser, comparer } + +static const typeinfo typeinfos[] = { +/* Must be in ascending order of rrtype ! */ +/* mem-mgmt code rrt fmt member parser comparer printer */ + + FLAT_TYPE(a, "A", 0, inaddr, pa_inaddr, di_inaddr, cs_inaddr), + DEEP_TYPE(ns_raw, "NS", "raw", str, pa_host_raw, 0, cs_domain), + DEEP_TYPE(cname, "CNAME", 0, str, pa_dom_raw, 0, cs_domain), + DEEP_TYPE(soa_raw, "SOA", "raw", soa, pa_soa, 0, cs_soa), + DEEP_TYPE(ptr_raw, "PTR", "raw", str, pa_host_raw, 0, cs_domain), + DEEP_TYPE(hinfo, "HINFO", 0, intstrpair, pa_hinfo, 0, cs_hinfo), + DEEP_TYPE(mx_raw, "MX", "raw", intstr, pa_mx_raw, di_mx_raw, + cs_inthost), + DEEP_TYPE(txt, "TXT", 0, manyistr, pa_txt, 0, cs_txt), + DEEP_TYPE(rp_raw, "RP", "raw", strpair, pa_rp, 0, cs_rp), + + FLAT_TYPE(addr, "A", "addr", addr, pa_addr, di_addr, cs_addr), + DEEP_TYPE(ns, "NS", "+addr", hostaddr, pa_hostaddr, di_hostaddr, + cs_hostaddr), + DEEP_TYPE(ptr, "PTR", "checked", str, pa_ptr, 0, cs_domain), + DEEP_TYPE(mx, "MX", "+addr", inthostaddr, pa_mx, di_mx, + cs_inthostaddr), + + DEEP_TYPE(soa, "SOA", "822", soa, pa_soa, 0, cs_soa), + DEEP_TYPE(rp, "RP", "822", strpair, pa_rp, 0, cs_rp), +}; + +const typeinfo *adns__findtype(adns_rrtype type) +{ + const typeinfo *begin, *end, *mid; + + begin = typeinfos; + end = typeinfos + (sizeof(typeinfos) / sizeof(typeinfo)); + + while (begin < end) { + mid = begin + ((end - begin) >> 1); + if (mid->type == type) + return mid; + if (type > mid->type) + begin = mid + 1; + else + end = mid; + } + return 0; +} diff --git a/client.c b/client.c new file mode 100644 index 0000000..7cbffa2 --- /dev/null +++ b/client.c @@ -0,0 +1,101 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** Portions Copyright (c) 1999 Johnathan George net@lite.net +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + +#include +#include +#include +#include +#include + +#include "defines.h" +#include "adns.h" +#include "conf.h" +#include "log.h" +#include "client.h" +#include "list.h" + +list_t *clientlist; + +int init_client_list() { + + clientlist = list_create(-1); + if (!clientlist) { + nlog(LOG_WARNING, LOG_CORE, "Warning, Client List create Failed"); + return NS_FAILURE; + } else { + return NS_SUCCESS; + } +} + + +mqclient *new_client(int fd) { + mqclient *mqc; + lnode_t *node; + + if (list_isfull(clientlist)) { + nlog(LOG_WARNING, LOG_CORE, "Client List Full. Bye Bye"); + do_exit(NS_EXIT_ERROR, "Client List Full"); + } + + mqc = malloc(sizeof(mqclient)); + bzero(mqc, sizeof(mqclient)); + mqc->type = MQC_TYPE_NONE; + mqc->fd = fd; + node = lnode_create(mqc); + mqc->node = node; + list_append(clientlist, node); + nlog(LOG_DEBUG3, LOG_CORE, "New Client on Fd %d", fd); +#ifdef DEBUG + if (!list_verify(clientlist)) { + nlog(LOG_WARNING, LOG_CORE, "Client Verify after insert failed"); + } +#endif + return mqc; +} + +static int list_find_fd(const void *key1, const void *key2) { + const mqclient *mqc1 = key1; + return ((int)key2 - mqc1->fd); +} + +mqclient *find_client_from_fd(int fd) { + lnode_t *node; + + node = list_find(clientlist, (void *)fd, list_find_fd); + if (!node) { + nlog(LOG_DEBUG1, LOG_CORE, "Can't Find Client for fd %d", fd); + return NULL; + } + return lnode_get(node); +} + +void del_client(mqclient *mqc) { + nlog(LOG_DEBUG1, LOG_CORE, "Deleting Client %s (%d)", mqc->user, mqc->fd); + list_delete(clientlist, mqc->node); + lnode_destroy(mqc->node); + free(mqc); +} diff --git a/client.h b/client.h new file mode 100644 index 0000000..cef4884 --- /dev/null +++ b/client.h @@ -0,0 +1,72 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + +#ifndef CLIENT_H +#define CLIENT_H + +#include "defines.h" +#include "event.h" +#include "list.h" + +typedef struct mqclient { + int fd; + char user[MAXNICK]; + char pass[MAXPASS]; + char host[MAXHOST]; + struct sockaddr_in ip; + long status; + long type; + struct event ev; + lnode_t *node; +} mqclient; + + +#define MQC_STAT_CONNECT 0x01 +#define MQC_STAT_DNSLKUP 0x02 +#define MQC_STAT_AUTHSTART 0x04 +#define MQC_STAT_AUTHOK 0x08 + +#define MQC_TYPE_NONE 0x01 +#define MQC_TYPE_LISTEN 0x02 +#define MQC_TYPE_CLIENT 0x04 +#define MQC_TYPE_ADMIN 0x08 +#define MQC_TYPE_REPL 0x10 + +#define MQC_SET_TYPE_LISTEN(x) x->type = MQC_TYPE_LISTEN +#define MQC_IS_TYPE_LISTEN(x) (x->type & MQC_TYPE_LISTEN) +#define MQC_CLEAR_TYPE_LISTEN(x) (x->type &= MQC_TYPE_LISTEN) + +#define MQC_SET_STAT_CONNECT(x) x->status |= MQC_STAT_CONNECT +#define MQC_IS_STAT_CONNECT(x) (x->status & MQC_STAT_CONNECT) +#define MQC_CLEAR_STAT_CONNECT(x) (x->status &= MQC_STAT_CONNECT); + +#define MQC_SET_STAT_DNSLOOKUP(x) x->status |= MQC_STAT_DNSLKUP +#define MQC_IS_STAT_DNSLOOKUP(x) (x->status & MQC_STAT_DNSLKUP) +#define MQC_CLEAR_STAT_DNSLOOKUP(x) (x->status &= MQC_STAT_DNSLKUP); + + +mqclient *new_client(int); +void del_client(mqclient *); +#endif diff --git a/conf.c b/conf.c new file mode 100644 index 0000000..b16b804 --- /dev/null +++ b/conf.c @@ -0,0 +1,157 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + +#include "defines.h" +#include "dotconf.h" +#include "conf.h" +#include "log.h" + +static void cb_Server (char *, int); + +/** @brief Core Configuration Items + * + * Contains Configuration Items for the Core NeoStats service + */ +static config_option options[] = { + {"SERVER_NAME", ARG_STR, cb_Server, 0}, + {"SERVER_PORT", ARG_STR, cb_Server, 1}, + {"CONNECT_TO", ARG_STR, cb_Server, 2}, + {"CONNECT_PASS", ARG_STR, cb_Server, 3}, + {"SERVER_INFOLINE", ARG_STR, cb_Server, 4}, + {"STATSERV_NETNAME", ARG_STR, cb_Server, 5}, + {"RECONNECT_TIME", ARG_STR, cb_Server, 6}, + {"NEOSTAT_HOST", ARG_STR, cb_Server, 7}, + {"NEOSTAT_USER", ARG_STR, cb_Server, 8}, + {"WANT_PRIVMSG", ARG_STR, cb_Server, 9}, + {"SERVICES_CHAN", ARG_STR, cb_Server, 10}, + {"ONLY_OPERS", ARG_STR, cb_Server, 11}, + {"NO_LOAD", ARG_STR, cb_Server, 12}, + {"BINDTO", ARG_STR, cb_Server, 13}, + {"LOGFILENAMEFORMAT", ARG_STR, cb_Server, 14}, + {"SERVER_NUMERIC", ARG_STR, cb_Server, 15}, + {"SETSERVERTIMES", ARG_STR, cb_Server, 16}, +}; + +/** @brief initialize the configuration parser + * + * Currently does nothing + * + * @return Nothing + */ + +void +init_conf () +{ +} + +/** @brief Load the Config file + * + * Parses the Configuration File and optionally loads the external authentication libary + * + * @returns Nothing + */ + +int +ConfLoad () +{ + /* Read in the Config File */ + printf ("Reading the Config File. Please wait.....\n"); + if (!config_read (CONFIG_NAME, options) == 0) { + printf ("***************************************************\n"); + printf ("* Error! *\n"); + printf ("* *\n"); + printf ("* Config File not found, or Unable to Open *\n"); + printf ("* Please check its Location, and try again *\n"); + printf ("* *\n"); + printf ("* NeoStats NOT Started *\n"); + printf ("***************************************************\n"); + return NS_FAILURE; + } + printf ("Sucessfully Loaded Config File, Now Booting NeoStats\n"); + + return NS_SUCCESS; +} + + +/** @brief Process config file items + * + * Processes the config file and sets up the variables. No Error Checking is performed :( + * + * @param arg the variable value as a string + * @param configtype the index of the variable being called now + * @returns Nothing + */ + +void +cb_Server (char *arg, int configtype) +{ + if (configtype == 0) { + /* Server name */ + strncpy (me.name, arg, sizeof (me.name)); + } else if (configtype == 1) { + /* Server Port */ + me.port = atoi (arg); + } else if (configtype == 2) { + } else if (configtype == 3) { + /* Connect Pass */ + strncpy (me.pass, arg, sizeof (me.pass)); + } else if (configtype == 4) { + } else if (configtype == 5) { + } else if (configtype == 6) { + /* Reconnect time */ + me.r_time = atoi (arg); + } else if (configtype == 7) { + /* NeoStat Host */ + strncpy (me.host, arg, MAXHOST); + } else if (configtype == 8) { + /* NeoStat User */ + strncpy (me.user, arg, MAXUSER); + } else if (configtype == 9) { + } else if (configtype == 10) { + } else if (configtype == 11) { + } else if (configtype == 12) { + me.die = 1; + } else if (configtype == 13) { + strncpy (me.local, arg, sizeof (me.local)); + } else if (configtype == 14) { + strncpy(LogFileNameFormat,arg,MAX_LOGFILENAME); + } else if (configtype == 15) { + } else if (configtype == 16) { + } + +} + +/** @brief Rehash Function + * + * Called when we recieve a rehash signal. Does nothing atm + * + * @returns Nothing + */ + +void +rehash () +{ + /* nothing, yet */ +} diff --git a/conf.h b/conf.h new file mode 100644 index 0000000..6ede856 --- /dev/null +++ b/conf.h @@ -0,0 +1,54 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + + +#ifndef _conf_h_ +#define _conf_h_ + +/* + * conf.h + * dynamic configuration runtime libary + */ + +/* define the config types */ + +#define CFGSTR 1 +#define CFGINT 2 +#define CFGFLOAT 3 +#define CFGBOOL 4 + +#define CONFBUFSIZE 256 + +int GetConf (void **data, int type, const char *item); +int SetConf (void *data, int type, char *item); +int GetDir (char *item, char ***data); +int DelConf (char *item); +int DelRow (char *table, char *row); +int DelTable(char *table); +int SetData (void *data, int type, char *table, char *row, char *field); +int GetTableData (char *table, char ***data); +int GetData (void **data, int type, const char *table, const char *row, const char *field); +void flush_keeper(); +#endif diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..ba66165 --- /dev/null +++ b/config.guess @@ -0,0 +1,1371 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. + +timestamp='2001-04-20' + +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# 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. + +# Written by Per Bothner . +# Please send patches to . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +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 ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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 + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c + for c in cc gcc c89 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break + fi + done + rm -f $dummy.c $dummy.o $dummy.rel + 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 + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +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 + +# 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 tupples: *-*-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. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-unknown ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE}" in + i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + 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 + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # 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 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # 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. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + 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 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + 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 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + 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 0 ;; + 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 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /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 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # 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 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* 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 $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + 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 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????: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 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + 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 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + 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 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | 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 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 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]) + case "${HPUX_REV}" in + 11.[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" ;; + esac ;; + esac + fi ;; + esac + if [ "${HP_ARCH}" = "" ]; then + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + 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 $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + 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 $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + 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 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + 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 i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + cat >$dummy.c < /* for printf() prototype */ +int main (int argc, char *argv[]) { +#else +int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __MIPSEB__ + printf ("%s-unknown-linux-gnu\n", argv[1]); +#endif +#ifdef __MIPSEL__ + printf ("%sel-unknown-linux-gnu\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + ;; + ppc:Linux:*:*) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unknown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then LIBC="libc1" ; fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 ;; + alpha:Linux:*:*) + cat <$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) UNAME_MACHINE="alpha" ;; + 1-0) UNAME_MACHINE="alphaev5" ;; + 1-1) UNAME_MACHINE="alphaev56" ;; + 1-101) UNAME_MACHINE="alphapca56" ;; + 2-303) UNAME_MACHINE="alphaev6" ;; + 2-307) UNAME_MACHINE="alphaev67" ;; + esac + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + 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-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_supported_emulations=`cd /; ld --help 2>&1 \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i*86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i*86) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + i*86coff) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 + ;; + esac + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + test -z "$ld_supported_emulations" && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + case "${UNAME_MACHINE}" in + i*86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; +# 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. + i*86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + 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 0 ;; + 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 0 ;; + i*86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + 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 i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + 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 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*: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 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *: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 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + 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 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[KW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *: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 0 ;; + 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 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#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 + 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"); 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 +# 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 $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# 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 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < 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: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..3caebad --- /dev/null +++ b/config.h.in @@ -0,0 +1,140 @@ +/* config.h.in. Generated from configure.in by autoheader. */ +/* Enable Debugging */ +#undef DEBUG + +/* Define to 1 if you have the header file. */ +#undef HAVE_DB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if your system has a working `fnmatch' function. */ +#undef HAVE_FNMATCH + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `dl' library (-ldl). */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `regcomp' function. */ +#undef HAVE_REGCOMP + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define if you have fcloseall */ +#undef HAVE_FCLOSEALL + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRNDUP + +/* Define to 1 if you have the `strftime' function. */ +#undef HAVE_STRFTIME + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strlcat' function. */ +#undef HAVE_STRLCAT + +/* Define to 1 if you have the `strnlen' function. */ +#undef HAVE_STRNLEN + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `unsigned' if does not define. */ +#undef size_t + +/* define if you have Backtrace */ +#undef HAVE_BACKTRACE + +/* Version number of package */ +#undef MQSERVER_PACKAGE_VERSION + +/* Install directory */ +#undef NEO_PREFIX + +/* Major Version */ +#undef MAJOR + +/* Minor Version */ +#undef MINOR + +/* Revision Version */ +#undef REV + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Have pthread mutex locking and unlocking functions in libc */ +#undef HAVE_PTHREAD_MUTEX + + diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..a06a480 --- /dev/null +++ b/config.sub @@ -0,0 +1,1362 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. + +timestamp='2001-04-20' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# 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. + +# Please send patches to . +# +# 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. + +# 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 ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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 0;; + + * ) + 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* | storm-chaos* | os2-emx*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + 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) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -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/'` + ;; + -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*) + 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. + tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \ + | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \ + | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | sh[34] \ + | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp10 | pdp11 \ + | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el | mcore | s390 | s390x \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \ + | v850 | c4x \ + | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \ + | pj | pjl | h8500) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | w65) + ;; + + # 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. + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \ + | arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp10-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \ + | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \ + | [cjt]90-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \ + | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*) + ;; + # 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 + ;; + 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 + ;; + 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 + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + 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 | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [cjt]90) + basic_machine=${basic_machine}-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + 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'm not sure what "Sysv32" means. Should this be sysv3.2? + 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 + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + 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 + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + 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 + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) 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/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-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 + ;; + 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=t3e-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + 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 + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-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 + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + 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 + ;; + sh3 | sh4) + basic_machine=sh-unknown + ;; + sparc | sparcv9 | sparcv9b) + 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 + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-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. + -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* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -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 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -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 + ;; + -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 + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + 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 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-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 + ;; + -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 + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..41ec359 --- /dev/null +++ b/configure @@ -0,0 +1,5758 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.57. +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +# 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 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+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; 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 + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + 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 + + ;; + 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 + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # 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 sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="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="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="main.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CPP EGREP LIBDB MAKEDEPENDENCIES DIRINST MODLDFLAGS LINK_SIZE MATCH_LIMIT NEWLINE UTF8 PACKAGE VERSION LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# 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. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +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 + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -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 | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$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 ;; + + -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 ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + 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 ;; + + -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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=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 ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + 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'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +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 + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + 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 + + +# 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 its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + 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 + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# 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 this package 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 \`..'] + +_ACEOF + + cat <<_ACEOF +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] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --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] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-debug - Enable Debuging + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style 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 + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +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 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.57. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +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` +hostinfo = `(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=. + echo "PATH: $as_dir" +done + +} >&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_sep= +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=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$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 + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core core.* *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >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 + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + 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. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +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 `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; 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,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +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 + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`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. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +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_config_headers="$ac_config_headers config.h" + +PACKAGE=MQServer +MAJOR=0 +MINOR=0 +REV=1 +cat >>confdefs.h <<_ACEOF +#define MAJOR $MAJOR +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define MINOR $MINOR +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define REV $REV +_ACEOF + +VERSION=$MAJOR.$MINOR.$REV +cat >>confdefs.h <<_ACEOF +#define MQSERVER_PACKAGE_VERSION "$VERSION" +_ACEOF + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; 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 + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +MYHOST=$host_os +case "$host_os" in +*cygwin) + CFLAGS="$CFLAGS -O2 -g" + LDFLAGS="$LDFLAGS -export-dynamic";; +*mingw32) + CFLAGS="$CFLAGS -O2 -g -mno-cygwin" + LDFLAGS="$LDFLAGS -export-dynamic";; +*openbsd) + CFLAGS="$CFLAGS -O2 -g -fPIC -DPIC" + LDFLAGS="-export-dynamic";; +*) + CFLAGS="$CFLAGS -O2 -g -fPIC -DPIC" + LDFLAGS="-rdynamic";; +esac + +case "$host_os" in +*openbsd*) + MAKEDEPENDENCIES="";; +*freebsd*) + MAKEDEPENDENCIES="";; +*) + MAKEDEPENDENCIES="-include \$(OBJS:.o=.d)";; +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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_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" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +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 + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + 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 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out 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. +echo "$as_me:$LINENO: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$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 +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* 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; +} +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 +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f 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 + +# 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" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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/* | \ + /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_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 + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +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. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$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' + +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, don't put newlines in cache variables' values. +# 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. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *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 \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + + +echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBDL 1 +_ACEOF + + LIBS="-ldl $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for backtrace" >&5 +echo $ECHO_N "checking for backtrace... $ECHO_C" >&6 +if test "${ac_cv_func_backtrace+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char backtrace (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char backtrace (); +/* 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_backtrace) || defined (__stub___backtrace) +choke me +#else +char (*f) () = backtrace; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != backtrace; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_backtrace=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_backtrace=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_backtrace" >&5 +echo "${ECHO_T}$ac_cv_func_backtrace" >&6 +if test $ac_cv_func_backtrace = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BACKTRACE 1 +_ACEOF + +LIBS="-g $LIBS" + +fi + +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, don't put newlines in cache variables' values. +# 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. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *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 \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + +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 +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 to if __STDC__ is defined, since + # 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 >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f 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 +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$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 to if __STDC__ is defined, since + # 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 >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +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 + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f 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 >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_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 >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_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 >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#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)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6 +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_sys_wait_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_sys_wait_h=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 +if test $ac_cv_header_sys_wait_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_WAIT_H 1 +_ACEOF + +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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + +for ac_header in sys/time.h unistd.h limits.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +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, don't put newlines in cache variables' values. +# 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. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *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 \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_const=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6 +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((size_t *) 0) + return 0; +if (sizeof (size_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_size_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned +_ACEOF + +fi + +echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_time=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6 +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 +echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6 +if test "${ac_cv_struct_tm+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +struct tm *tp; tp->tm_sec; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_struct_tm=time.h +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_struct_tm=sys/time.h +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 +echo "${ECHO_T}$ac_cv_struct_tm" >&6 +if test $ac_cv_struct_tm = sys/time.h; then + +cat >>confdefs.h <<\_ACEOF +#define TM_IN_SYS_TIME 1 +_ACEOF + +fi + +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, don't put newlines in cache variables' values. +# 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. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *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 \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +echo "$as_me:$LINENO: checking for working POSIX fnmatch" >&5 +echo $ECHO_N "checking for working POSIX fnmatch... $ECHO_C" >&6 +if test "${ac_cv_func_fnmatch_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Some versions of Solaris, SCO, and the GNU C Library + # have a broken or incompatible fnmatch. + # So we run a test program. If we are cross-compiling, take no chance. + # Thanks to John Oleynick, Franc,ois Pinard, and Paul Eggert for this test. + if test "$cross_compiling" = yes; then + ac_cv_func_fnmatch_works=cross +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +# define y(a, b, c) (fnmatch (a, b, c) == 0) +# define n(a, b, c) (fnmatch (a, b, c) == FNM_NOMATCH) + +int +main () +{ +exit + (!(y ("a*", "abc", 0) + && n ("d*/*1", "d/s/1", FNM_PATHNAME) + && y ("a\\\\bc", "abc", 0) + && n ("a\\\\bc", "abc", FNM_NOESCAPE) + && y ("*x", ".x", 0) + && n ("*x", ".x", FNM_PERIOD) + && 1)); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_fnmatch_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_fnmatch_works=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_fnmatch_works" >&5 +echo "${ECHO_T}$ac_cv_func_fnmatch_works" >&6 +if test $ac_cv_func_fnmatch_works = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_FNMATCH 1 +_ACEOF + +fi + + + +echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifdef signal +# undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_signal=void +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_signal=int +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6 + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + + +for ac_func in strftime +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + # strftime is in -lintl on SCO UNIX. +echo "$as_me:$LINENO: checking for strftime in -lintl" >&5 +echo $ECHO_N "checking for strftime in -lintl... $ECHO_C" >&6 +if test "${ac_cv_lib_intl_strftime+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strftime (); +int +main () +{ +strftime (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_intl_strftime=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_intl_strftime=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_intl_strftime" >&5 +echo "${ECHO_T}$ac_cv_lib_intl_strftime" >&6 +if test $ac_cv_lib_intl_strftime = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_STRFTIME 1 +_ACEOF + +LIBS="-lintl $LIBS" +fi + +fi +done + + + + +for ac_func in strlcpy strlcat strnlen +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +for ac_func in socket strdup +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in strndup +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + +for ac_func in bcopy memmove strerror +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + +for ac_header in sys/select.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to bug-autoconf@gnu.org. ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +echo "$as_me:$LINENO: checking Whether to Enable Debuging..." >&5 +echo $ECHO_N "checking Whether to Enable Debuging...... $ECHO_C" >&6 +# Check whether --enable-debug or --disable-debug was given. +if test "${enable_debug+set}" = set; then + enableval="$enable_debug" + case "$enableval" in + yes) + +cat >>confdefs.h <<\_ACEOF +#define DEBUG 1 +_ACEOF + + CFLAGS="$CFLAGS -ggdb -Wall" + echo "$as_me:$LINENO: result: yes - Watch your Log Files" >&5 +echo "${ECHO_T}yes - Watch your Log Files" >&6 + ;; + *) + CFLAGS="$CFLAGS -DNDEBUG" + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + ;; + esac +else + CFLAGS="$CFLAGS -DNDEBUG" +echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + +fi; + +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, don't put newlines in cache variables' values. +# 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. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *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 \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +if test "x${prefix}" = "xNONE"; then + cat >>confdefs.h <<_ACEOF +#define NEO_PREFIX "${ac_default_prefix}" +_ACEOF + +else + cat >>confdefs.h <<_ACEOF +#define NEO_PREFIX "${prefix}" +_ACEOF + +fi + + + # save our work to this point; this allows the sub-package to use it + 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, don't put newlines in cache variables' values. +# 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. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *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 \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + echo + echo "----------------------------------------------------------------" + echo "configuring package in libevent now" + echo "----------------------------------------------------------------" + ac_popdir=`pwd` + ac_abs_srcdir=`(cd $srcdir/libevent && pwd)` + apr_config_subdirs="libevent" + test -d libevent || $MKDIR libevent + cd libevent + + #changequote(, )dnl + # A "../" for each directory in /$config_subdirs. + #ac_dots=`echo $apr_config_subdirs|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` + #changequote([, ])dnl + + # Make the cache file name correct relative to the subdirectory. + case "$cache_file" in + /*) ac_sub_cache_file=$cache_file ;; + *) # Relative path. + ac_sub_cache_file="$ac_dots$cache_file" ;; + esac + + # The eval makes quoting arguments work. + if eval $ac_abs_srcdir/configure $ac_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_abs_srcdir --disable-shared --enable-static + then : + echo "libevent configured properly" + else + echo "configure failed for libevent" + exit 1 + fi + cd $ac_popdir + + # grab any updates from the sub-package + if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + + + + + + + + + + + + + + + + + + ac_config_files="$ac_config_files 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, don't put newlines in cache variables' values. +# 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. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *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 \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + 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}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ 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[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $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} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# 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+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; 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 + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + 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 + + ;; + 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 + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # 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 sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="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="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.57. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -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 + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.57, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +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=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + 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 +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + 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_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@LIBDB@,$LIBDB,;t t +s,@MAKEDEPENDENCIES@,$MAKEDEPENDENCIES,;t t +s,@DIRINST@,$DIRINST,;t t +s,@MODLDFLAGS@,$MODLDFLAGS,;t t +s,@LINK_SIZE@,$LINK_SIZE,;t t +s,@MATCH_LIMIT@,$MATCH_LIMIT,;t t +s,@NEWLINE@,$NEWLINE,;t t +s,@UTF8@,$UTF8,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # 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. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;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,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # 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. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# 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 || { (exit 1); exit 1; } +fi + +echo "(*----------------------------------------------------------*)" +echo "(| Important Instructions |)" +echo "(*----------------------------------------------------------*)" +echo "(| if you just typed ./configure and didnt read the README |)" +echo "(| NeoStats may not be configured correctly. |)" +echo "(| We suggest you at least type ./configure --help to see |)" +echo "(| available options and read the README file for further |)" +echo "(| information on that option. |)" +echo "(*----------------------------------------------------------*)" +echo "(| For Support please visit: |)" +echo "(| IRC: /server irc.irc-chat.net |)" +echo "(| #neostats channel |)" +echo "(| WWW: http://www.neostats.net/boards/ |)" +echo "(*----------------------------------------------------------*)" +echo "(| Now that configure is complete, type 'make' to compile |)" +echo "(| the program. When the compile has completed, type |)" +echo "(| 'make install' to install the program. |)" +echo "(| For BSD you might need to use 'gmake' and 'gmake install'|)" +echo "(*----------------------------------------------------------*)" +#if test "$shush" != yes; then +# read -p "Press Enter Key to Read the Release Notes" +# clear +# more ./RELNOTES +#fi diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..a8d810c --- /dev/null +++ b/configure.in @@ -0,0 +1,150 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(main.c) +AC_CONFIG_HEADER(config.h) +PACKAGE=MQServer +MAJOR=0 +MINOR=0 +REV=1 +AC_DEFINE_UNQUOTED(MAJOR, $MAJOR) +AC_DEFINE_UNQUOTED(MINOR, $MINOR) +AC_DEFINE_UNQUOTED(REV, $REV) +VERSION=$MAJOR.$MINOR.$REV +AC_DEFINE_UNQUOTED(MQSERVER_PACKAGE_VERSION, "$VERSION") + +dnl Get system type +AC_CANONICAL_HOST +MYHOST=$host_os +case "$host_os" in +*cygwin) + CFLAGS="$CFLAGS -O2 -g" + LDFLAGS="$LDFLAGS -export-dynamic";; +*mingw32) + CFLAGS="$CFLAGS -O2 -g -mno-cygwin" + LDFLAGS="$LDFLAGS -export-dynamic";; +*openbsd) + CFLAGS="$CFLAGS -O2 -g -fPIC -DPIC" + LDFLAGS="-export-dynamic";; +*) + CFLAGS="$CFLAGS -O2 -g -fPIC -DPIC" + LDFLAGS="-rdynamic";; +esac + +case "$host_os" in +*openbsd*) + MAKEDEPENDENCIES="";; +*freebsd*) + MAKEDEPENDENCIES="";; +*) + MAKEDEPENDENCIES="-include \$(OBJS:.o=.d)";; +esac + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_INSTALL +AC_CACHE_SAVE + +dnl Checks for libraries. +dnl Replace `main' with a function in -ldl: +AC_CHECK_LIB(dl, dlopen) + +AC_CHECK_FUNC(backtrace, +[AC_DEFINE(HAVE_BACKTRACE, 1, 'backtrace function available') +LIBS="-g $LIBS"] +) +AC_CACHE_SAVE + + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(sys/time.h unistd.h limits.h) +AC_CACHE_SAVE + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_STRUCT_TM +AC_CACHE_SAVE + +dnl Checks for library functions. +AC_FUNC_FNMATCH +AC_TYPE_SIGNAL +AC_FUNC_STRFTIME +AC_CHECK_FUNCS(strlcpy strlcat strnlen) +AC_CHECK_FUNCS(socket strdup) +AC_CHECK_FUNCS(strndup) +AC_CHECK_FUNCS(bcopy memmove strerror) + + +AC_CHECK_HEADERS(sys/select.h) + +dnl check if we are running with Debug.... +AC_MSG_CHECKING(Whether to Enable Debuging...) +AC_ARG_ENABLE(debug, +[ --enable-debug - Enable Debuging], +[ case "$enableval" in + yes) + AC_DEFINE(DEBUG, 1, 'Enable Debugging') + CFLAGS="$CFLAGS -ggdb -Wall" + AC_MSG_RESULT(yes - Watch your Log Files) + ;; + *) + CFLAGS="$CFLAGS -DNDEBUG" + AC_MSG_RESULT(no) + ;; + esac], +CFLAGS="$CFLAGS -DNDEBUG" +AC_MSG_RESULT(no) +) + +AC_CACHE_SAVE + +dnl Set NEO_PREFIX in config.h. +if test "x${prefix}" = "xNONE"; then + AC_DEFINE_UNQUOTED(NEO_PREFIX, "${ac_default_prefix}") +else + AC_DEFINE_UNQUOTED(NEO_PREFIX, "${prefix}") +fi + +NEO_SUBDIR_CONFIG(libevent, [--disable-shared --enable-static]) + +AC_SUBST(LIBDB) +AC_SUBST(MAKEDEPENDENCIES) +AC_SUBST(DIRINST) +AC_SUBST(CFLAGS) +AC_SUBST(LDFLAGS) +AC_SUBST(MODLDFLAGS) +AC_SUBST(LINK_SIZE) +AC_SUBST(MATCH_LIMIT) +AC_SUBST(NEWLINE) +AC_SUBST(UTF8) + +AC_SUBST(LIBS) +AC_SUBST(PACKAGE) +AC_SUBST(VERSION) +AC_OUTPUT(Makefile) +echo "(*----------------------------------------------------------*)" +echo "(| Important Instructions |)" +echo "(*----------------------------------------------------------*)" +echo "(| if you just typed ./configure and didnt read the README |)" +echo "(| NeoStats may not be configured correctly. |)" +echo "(| We suggest you at least type ./configure --help to see |)" +echo "(| available options and read the README file for further |)" +echo "(| information on that option. |)" +echo "(*----------------------------------------------------------*)" +echo "(| For Support please visit: |)" +echo "(| IRC: /server irc.irc-chat.net |)" +echo "(| #neostats channel |)" +echo "(| WWW: http://www.neostats.net/boards/ |)" +echo "(*----------------------------------------------------------*)" +echo "(| Now that configure is complete, type 'make' to compile |)" +echo "(| the program. When the compile has completed, type |)" +echo "(| 'make install' to install the program. |)" +echo "(| For BSD you might need to use 'gmake' and 'gmake install'|)" +echo "(*----------------------------------------------------------*)" +#if test "$shush" != yes; then +# read -p "Press Enter Key to Read the Release Notes" +# clear +# more ./RELNOTES +#fi \ No newline at end of file diff --git a/defines.h b/defines.h new file mode 100644 index 0000000..784c2f9 --- /dev/null +++ b/defines.h @@ -0,0 +1,225 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + +#ifndef DEFINES_H +#define DEFINES_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define __USE_GNU +#include +#undef __USE_GNU +#include +#include +#include +#include +#include +#include +#include +#include +#include "event.h" +#include "config.h" + +#ifdef HAVE_DB_H +/*#define USE_BERKELEY*/ +#endif + +/* Temp disable for upcoming release until all external modules + * have been released with warnings fixed + */ +#if 0 +#define __attribute__(x) /* NOTHING */ +#else +/* If we're not using GNU C, elide __attribute__ */ +#ifndef __GNUC__ +#define __attribute__(x) /* NOTHING */ +#endif +#endif + +#include "list.h" +#include "hash.h" +#include "adns.h" + +#ifdef MQSERVER_REVISION +#define MQSERVER_VERSION MQSERVER_PACKAGE_VERSION " (" MQSERVER_REVISION ")" +#else +#define MQSERVER_VERSION MQSERVER_PACKAGE_VERSION +#endif + +#define CONFIG_NAME "mqserver.cfg" +#define PID_FILENAME "mqserver.pid" + +#define BUFSIZE 512 +#ifndef MAXHOST +#define MAXHOST 128 +#endif +#ifndef MAXPASS +#define MAXPASS 32 +#endif +#ifndef MAXNICK +#define MAXNICK 32 +#endif +#ifndef MAXUSER +#define MAXUSER 15 +#endif +#ifndef MAXREALNAME +#define MAXREALNAME 50 +#endif + +/* MAXPATH + * used to determine buffer sizes for file system operations + */ +#ifndef MAXPATH +#define MAXPATH 1024 +#endif /* MAXPATH */ + +/* TIMEBUFSIZE + * used to determine buffer sizes for time formatting buffers + */ +#define TIMEBUFSIZE 80 + +/* STR_TIME_T_SIZE + * size of a time_t converted to a string. + */ +#define STR_TIME_T_SIZE 24 + +/* Buffer size for version string */ +#define VERSIONSIZE 32 + +#define bzero(x, y) memset(x, '\0', y); + +/* Early creation of unified return values and error system */ +/* These are program exit codes usually defined in stdlib.h but + if not found will be defined here */ +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif /* EXIT_FAILURE */ +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif /* EXIT_SUCCESS */ + +#define NS_SUCCESS 1 +#define NS_FAILURE -1 + +/* Specific errors beyond SUCCESS/FAILURE so that functions can handle errors + * Treat as unsigned with top bit set to give us a clear distinction from + * other values and use a typedef ENUM so that we can indicate return type */ +typedef enum NS_ERR { + NS_ERR_NICK_IN_USE = 0x8000001, + NS_ERR_OUT_OF_MEMORY = 0x8000002, + NS_ERR_VERSION = 0x8000003, +}NS_ERR ; + + +/* do_exit call exit type definitions */ +typedef enum { + NS_EXIT_NORMAL=0, + NS_EXIT_RELOAD, + NS_EXIT_RECONNECT, + NS_EXIT_ERROR, + NS_EXIT_SEGFAULT, +}NS_EXIT_TYPE; + +#define SEGV_LOCATION_BUFSIZE 255 +#define SET_SEGV_LOCATION() snprintf(segv_location,SEGV_LOCATION_BUFSIZE,"%s %d %s", __FILE__, __LINE__, __PRETTY_FUNCTION__); +#define SET_SEGV_LOCATION_EXTRA(debug_text) snprintf(segv_location,SEGV_LOCATION_BUFSIZE,"%s %d %s %s", __FILE__, __LINE__, __PRETTY_FUNCTION__,(debug_text)); +#define CLEAR_SEGV_LOCATION() segv_location[0]='\0'; + +#define SEGV_INMODULE_BUFSIZE 255 +#define SET_SEGV_INMODULE(module_name) strncpy(segv_inmodule,(module_name),SEGV_INMODULE_BUFSIZE); +#define CLEAR_SEGV_INMODULE() segv_inmodule[0]='\0'; + +/* macros to provide a couple missing string functions for code legibility + * and to ensure we perform these operations in a standard and optimal manner + */ +/* set a string to NULL */ +#define strsetnull(str) (str)[0] = 0 +/* test a string for NULL */ +#define strisnull(str) ((str) && (str)[0] == 0) + +#define ARRAY_COUNT (a) ((sizeof ((a)) / sizeof ((a)[0])) + +extern char segv_location[SEGV_LOCATION_BUFSIZE]; +extern char segv_inmodule[SEGV_INMODULE_BUFSIZE]; +extern jmp_buf sigvbuf; + +/* this is the dns structure */ +extern adns_state ads; + + +/* version info */ +extern const char version_date[], version_time[]; + +/** @brief me structure + * structure containing information about the neostats core + */ +struct me { + char name[MAXHOST]; + int port; + int r_time; + char pass[MAXPASS]; + char local[MAXHOST]; + char user[MAXUSER]; /* bot user */ + char host[MAXHOST]; /* bot host */ + char realname[MAXREALNAME]; /* bot real name */ + time_t t_start; + unsigned int die:1; + unsigned int debug_mode:1; + time_t now; + char strnow[STR_TIME_T_SIZE]; + char version[VERSIONSIZE]; + char versionfull[VERSIONSIZE]; +} me; + +/* conf.c */ +int ConfLoad (void); +void rehash (void); +int ConfLoadModules (void); + +/* main.c */ +void do_exit (NS_EXIT_TYPE exitcode, char* quitmsg) __attribute__((noreturn)); +void fatal_error(char* file, int line, char* func, char* error_text) __attribute__((noreturn));; +#define FATAL_ERROR(error_text) fatal_error(__FILE__, __LINE__, __PRETTY_FUNCTION__,(error_text)); + +/* misc.c */ +void strip (char * line); +void *smalloc (long size); +char *sstrdup (const char * s); +char *strlwr (char * s); +void AddStringToList (char ***List, char S[], int *C); +char *sctime (time_t t); +char *sftime (time_t t); + + + +#endif + diff --git a/dict.c b/dict.c new file mode 100644 index 0000000..120b024 --- /dev/null +++ b/dict.c @@ -0,0 +1,1142 @@ +/* + * Dictionary Abstract Data Type + * Copyright (C) 1997 Kaz Kylheku + * + * Free Software License: + * + * All rights are reserved by the author, with the following exceptions: + * Permission is granted to freely reproduce and distribute this software, + * possibly in exchange for a fee, provided that this copyright notice appears + * intact. Permission is also granted to adapt this software to produce + * derivative works, as long as the modified versions carry this copyright + * notice and additional notices stating that the work has been modified. + * This source code may be translated into executable form and incorporated + * into proprietary software; there is no requirement for such software to + * contain a copyright notice related to this source. + * + * $Id$ + * $Name: kazlib_1_15 $ + */ + +#include +#include +#include +#define DICT_IMPLEMENTATION +#include "dict.h" + +#ifdef KAZLIB_RCSID +static const char rcsid[] = "$Id$"; +#endif + +/* + * These macros provide short convenient names for structure members, + * which are embellished with dict_ prefixes so that they are + * properly confined to the documented namespace. It's legal for a + * program which uses dict to define, for instance, a macro called ``parent''. + * Such a macro would interfere with the dnode_t struct definition. + * In general, highly portable and reusable C modules which expose their + * structures need to confine structure member names to well-defined spaces. + * The resulting identifiers aren't necessarily convenient to use, nor + * readable, in the implementation, however! + */ + +#define left dict_left +#define right dict_right +#define parent dict_parent +#define color dict_color +#define key dict_key +#define data dict_data + +#define nilnode dict_nilnode +#define nodecount dict_nodecount +#define maxcount dict_maxcount +#define compare dict_compare +#define allocnode dict_allocnode +#define freenode dict_freenode +#define context dict_context +#define dupes dict_dupes + +#define dict_root(D) ((D)->nilnode.left) +#define dict_nil(D) (&(D)->nilnode) + +static dnode_t *dnode_alloc(void *context); +static void dnode_free(dnode_t *node, void *context); + +/* + * Perform a ``left rotation'' adjustment on the tree. The given node P and + * its right child C are rearranged so that the P instead becomes the left + * child of C. The left subtree of C is inherited as the new right subtree + * for P. The ordering of the keys within the tree is thus preserved. + */ + +static void rotate_left(dict_t *dict, dnode_t *upper) +{ + dnode_t *lower, *lowleft, *upparent; + + assert (upper != dict_nil(dict)); + assert (upper->right != dict_nil(dict)); + + lower = upper->right; + upper->right = lowleft = lower->left; + lowleft->parent = upper; + + lower->parent = upparent = upper->parent; + + /* don't need to check for root node here because root->parent is + the sentinel nil node, and root->parent->left points back to root */ + + if (upper == upparent->left) { + upparent->left = lower; + } else { + assert (upper == upparent->right); + upparent->right = lower; + } + + lower->left = upper; + upper->parent = lower; +} + +/* + * This operation is the ``mirror'' image of rotate_left. It is + * the same procedure, but with left and right interchanged. + */ + +static void rotate_right(dict_t *dict, dnode_t *upper) +{ + dnode_t *lower, *lowright, *upparent; + + assert (upper != dict_nil(dict)); + assert (upper->left != dict_nil(dict)); + + lower = upper->left; + upper->left = lowright = lower->right; + lowright->parent = upper; + + lower->parent = upparent = upper->parent; + + if (upper == upparent->right) { + upparent->right = lower; + } else { + assert (upper == upparent->left); + upparent->left = lower; + } + + lower->right = upper; + upper->parent = lower; +} + +/* + * This procedure performs a verification that the given subtree is a binary + * search tree. It performs an inorder traversal of the tree using the + * dict_next() successor function, verifying that the key of each node is + * strictly lower than that of its successor, if duplicates are allowed, + * or lower or equal if duplicates are not allowed. This function is used for + * debugging purposes. + */ + +static int verify_bintree(dict_t *dict) +{ + dnode_t *first, *next; + + first = dict_first(dict); + + if (dict->dupes) { + while (first && (next = dict_next(dict, first))) { + if (dict->compare(first->key, next->key) > 0) + return 0; + first = next; + } + } else { + while (first && (next = dict_next(dict, first))) { + if (dict->compare(first->key, next->key) >= 0) + return 0; + first = next; + } + } + return 1; +} + + +/* + * This function recursively verifies that the given binary subtree satisfies + * three of the red black properties. It checks that every red node has only + * black children. It makes sure that each node is either red or black. And it + * checks that every path has the same count of black nodes from root to leaf. + * It returns the blackheight of the given subtree; this allows blackheights to + * be computed recursively and compared for left and right siblings for + * mismatches. It does not check for every nil node being black, because there + * is only one sentinel nil node. The return value of this function is the + * black height of the subtree rooted at the node ``root'', or zero if the + * subtree is not red-black. + */ + +static unsigned int verify_redblack(dnode_t *nil, dnode_t *root) +{ + unsigned height_left, height_right; + + if (root != nil) { + height_left = verify_redblack(nil, root->left); + height_right = verify_redblack(nil, root->right); + if (height_left == 0 || height_right == 0) + return 0; + if (height_left != height_right) + return 0; + if (root->color == dnode_red) { + if (root->left->color != dnode_black) + return 0; + if (root->right->color != dnode_black) + return 0; + return height_left; + } + if (root->color != dnode_black) + return 0; + return height_left + 1; + } + return 1; +} + +/* + * Compute the actual count of nodes by traversing the tree and + * return it. This could be compared against the stored count to + * detect a mismatch. + */ + +static dictcount_t verify_node_count(dnode_t *nil, dnode_t *root) +{ + if (root == nil) + return 0; + else + return 1 + verify_node_count(nil, root->left) + + verify_node_count(nil, root->right); +} + +/* + * Verify that the tree contains the given node. This is done by + * traversing all of the nodes and comparing their pointers to the + * given pointer. Returns 1 if the node is found, otherwise + * returns zero. It is intended for debugging purposes. + */ + +static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node) +{ + if (root != nil) { + return root == node + || verify_dict_has_node(nil, root->left, node) + || verify_dict_has_node(nil, root->right, node); + } + return 0; +} + + +/* + * Dynamically allocate and initialize a dictionary object. The safe malloc + * routines are used for improved correctness verification. + */ + +dict_t *dict_create(dictcount_t maxcount, dict_comp_t comp) +{ + dict_t *new = malloc(sizeof *new); + + if (new) { + new->compare = comp; + new->allocnode = dnode_alloc; + new->freenode = dnode_free; + new->context = NULL; + new->nodecount = 0; + new->maxcount = maxcount; + new->nilnode.left = &new->nilnode; + new->nilnode.right = &new->nilnode; + new->nilnode.parent = &new->nilnode; + new->nilnode.color = dnode_black; + new->dupes = 0; + } + return new; +} + +/* + * Select a different set of node allocator routines. + */ + +void dict_set_allocator(dict_t *dict, dnode_alloc_t al, + dnode_free_t fr, void *context) +{ + assert (dict_count(dict) == 0); + assert ((al == 0 && fr == 0) || (al != 0 && fr != 0)); + + dict->allocnode = al ? al : dnode_alloc; + dict->freenode = fr ? fr : dnode_free; + dict->context = context; +} + +/* + * Free a dynamically allocated dictionary object. Removing the nodes + * from the tree before deleting it is required. + */ + +void dict_destroy(dict_t *dict) +{ + assert (dict_isempty(dict)); + free(dict); +} + +/* + * Free all the nodes in the dictionary by using the dictionary's + * installed free routine. + */ + +extern void dict_free(dict_t *dict) +{ + dnode_t *node = dict_first(dict); + + while (node) { + dnode_t *next = dict_next(dict, node); + dict_delete(dict, node); + dict->freenode(node, dict->context); + node = next; + } +} + +/* + * Initialize a user-supplied dictionary object. + */ + +dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp) +{ + dict->compare = comp; + dict->allocnode = dnode_alloc; + dict->freenode = dnode_free; + dict->context = NULL; + dict->nodecount = 0; + dict->maxcount = maxcount; + dict->nilnode.left = &dict->nilnode; + dict->nilnode.right = &dict->nilnode; + dict->nilnode.parent = &dict->nilnode; + dict->nilnode.color = dnode_black; + dict->dupes = 0; + return dict; +} + +/* + * Verify the integrity of the dictionary structure. This is provided for + * debugging purposes, and should be placed in assert statements. Just because + * this function succeeds doesn't mean that the tree is not corrupt. Certain + * corruptions in the tree may simply cause undefined behavior. + */ + +int dict_verify(dict_t *dict) +{ + dnode_t *nil = dict_nil(dict), *root = dict_root(dict); + + /* check that the sentinel node and root node are black */ + if (root->color != dnode_black) + return 0; + if (nil->color != dnode_black) + return 0; + if (nil->right != nil) + return 0; + /* nil->left is the root node; check that its parent pointer is nil */ + if (nil->left->parent != nil) + return 0; + /* perform a weak test that the tree is a binary search tree */ + if (!verify_bintree(dict)) + return 0; + /* verify that the tree is a red-black tree */ + if (!verify_redblack(nil, root)) + return 0; + if (verify_node_count(nil, root) != dict_count(dict)) + return 0; + return 1; +} + +/* + * Locate a node in the dictionary having the given key. + * If the node is not found, a null a pointer is returned (rather than + * a pointer that dictionary's nil sentinel node), otherwise a pointer to the + * located node is returned. + */ + +dnode_t *dict_lookup(dict_t *dict, const void *key) +{ + dnode_t *root = dict_root(dict); + dnode_t *nil = dict_nil(dict); + dnode_t *saved; + int result; + + /* simple binary search adapted for trees that contain duplicate keys */ + + while (root != nil) { + result = dict->compare(key, root->key); + if (result < 0) + root = root->left; + else if (result > 0) + root = root->right; + else { + if (!dict->dupes) { /* no duplicates, return match */ + return root; + } else { /* could be dupes, find leftmost one */ + do { + saved = root; + root = root->left; + while (root != nil && dict->compare(key, root->key)) + root = root->right; + } while (root != nil); + return saved; + } + } + } + + return NULL; +} + +/* + * Look for the node corresponding to the lowest key that is equal to or + * greater than the given key. If there is no such node, return null. + */ + +dnode_t *dict_lower_bound(dict_t *dict, void *key) +{ + dnode_t *root = dict_root(dict); + dnode_t *nil = dict_nil(dict); + dnode_t *tentative = 0; + + while (root != nil) { + int result = dict->compare(key, root->key); + + if (result > 0) { + root = root->right; + } else if (result < 0) { + tentative = root; + root = root->left; + } else { + if (!dict->dupes) { + return root; + } else { + tentative = root; + root = root->left; + } + } + } + + return tentative; +} + +/* + * Look for the node corresponding to the lowest key that is equal to or + * greater than the given key. If there is no such node, return null. + */ + +dnode_t *dict_upper_bound(dict_t *dict, void *key) +{ + dnode_t *root = dict_root(dict); + dnode_t *nil = dict_nil(dict); + dnode_t *tentative = 0; + + while (root != nil) { + int result = dict->compare(key, root->key); + + if (result < 0) { + root = root->left; + } else if (result > 0) { + tentative = root; + root = root->right; + } else { + if (!dict->dupes) { + return root; + } else { + tentative = root; + root = root->right; + } + } + } + + return tentative; +} + +/* + * Insert a node into the dictionary. The node should have been + * initialized with a data field. All other fields are ignored. + * The behavior is undefined if the user attempts to insert into + * a dictionary that is already full (for which the dict_isfull() + * function returns true). + */ + +void dict_insert(dict_t *dict, dnode_t *node, const void *key) +{ + dnode_t *where = dict_root(dict), *nil = dict_nil(dict); + dnode_t *parent = nil, *uncle, *grandpa; + int result = -1; + + node->key = key; + + assert (!dict_isfull(dict)); + assert (!dict_contains(dict, node)); + assert (!dnode_is_in_a_dict(node)); + + /* basic binary tree insert */ + + while (where != nil) { + parent = where; + result = dict->compare(key, where->key); + /* trap attempts at duplicate key insertion unless it's explicitly allowed */ + assert (dict->dupes || result != 0); + if (result < 0) + where = where->left; + else + where = where->right; + } + + assert (where == nil); + + if (result < 0) + parent->left = node; + else + parent->right = node; + + node->parent = parent; + node->left = nil; + node->right = nil; + + dict->nodecount++; + + /* red black adjustments */ + + node->color = dnode_red; + + while (parent->color == dnode_red) { + grandpa = parent->parent; + if (parent == grandpa->left) { + uncle = grandpa->right; + if (uncle->color == dnode_red) { /* red parent, red uncle */ + parent->color = dnode_black; + uncle->color = dnode_black; + grandpa->color = dnode_red; + node = grandpa; + parent = grandpa->parent; + } else { /* red parent, black uncle */ + if (node == parent->right) { + rotate_left(dict, parent); + parent = node; + assert (grandpa == parent->parent); + /* rotation between parent and child preserves grandpa */ + } + parent->color = dnode_black; + grandpa->color = dnode_red; + rotate_right(dict, grandpa); + break; + } + } else { /* symmetric cases: parent == parent->parent->right */ + uncle = grandpa->left; + if (uncle->color == dnode_red) { + parent->color = dnode_black; + uncle->color = dnode_black; + grandpa->color = dnode_red; + node = grandpa; + parent = grandpa->parent; + } else { + if (node == parent->left) { + rotate_right(dict, parent); + parent = node; + assert (grandpa == parent->parent); + } + parent->color = dnode_black; + grandpa->color = dnode_red; + rotate_left(dict, grandpa); + break; + } + } + } + + dict_root(dict)->color = dnode_black; + + assert (dict_verify(dict)); +} + +/* + * Delete the given node from the dictionary. If the given node does not belong + * to the given dictionary, undefined behavior results. A pointer to the + * deleted node is returned. + */ + +dnode_t *dict_delete(dict_t *dict, dnode_t *delete) +{ + dnode_t *nil = dict_nil(dict), *child, *delparent = delete->parent; + + /* basic deletion */ + + assert (!dict_isempty(dict)); + assert (dict_contains(dict, delete)); + + /* + * If the node being deleted has two children, then we replace it with its + * successor (i.e. the leftmost node in the right subtree.) By doing this, + * we avoid the traditional algorithm under which the successor's key and + * value *only* move to the deleted node and the successor is spliced out + * from the tree. We cannot use this approach because the user may hold + * pointers to the successor, or nodes may be inextricably tied to some + * other structures by way of embedding, etc. So we must splice out the + * node we are given, not some other node, and must not move contents from + * one node to another behind the user's back. + */ + + if (delete->left != nil && delete->right != nil) { + dnode_t *next = dict_next(dict, delete); + dnode_t *nextparent = next->parent; + dnode_color_t nextcolor = next->color; + + assert (next != nil); + assert (next->parent != nil); + assert (next->left == nil); + + /* + * First, splice out the successor from the tree completely, by + * moving up its right child into its place. + */ + + child = next->right; + child->parent = nextparent; + + if (nextparent->left == next) { + nextparent->left = child; + } else { + assert (nextparent->right == next); + nextparent->right = child; + } + + /* + * Now that the successor has been extricated from the tree, install it + * in place of the node that we want deleted. + */ + + next->parent = delparent; + next->left = delete->left; + next->right = delete->right; + next->left->parent = next; + next->right->parent = next; + next->color = delete->color; + delete->color = nextcolor; + + if (delparent->left == delete) { + delparent->left = next; + } else { + assert (delparent->right == delete); + delparent->right = next; + } + + } else { + assert (delete != nil); + assert (delete->left == nil || delete->right == nil); + + child = (delete->left != nil) ? delete->left : delete->right; + + child->parent = delparent = delete->parent; + + if (delete == delparent->left) { + delparent->left = child; + } else { + assert (delete == delparent->right); + delparent->right = child; + } + } + + delete->parent = NULL; + delete->right = NULL; + delete->left = NULL; + + dict->nodecount--; + + assert (verify_bintree(dict)); + + /* red-black adjustments */ + + if (delete->color == dnode_black) { + dnode_t *parent, *sister; + + dict_root(dict)->color = dnode_red; + + while (child->color == dnode_black) { + parent = child->parent; + if (child == parent->left) { + sister = parent->right; + assert (sister != nil); + if (sister->color == dnode_red) { + sister->color = dnode_black; + parent->color = dnode_red; + rotate_left(dict, parent); + sister = parent->right; + assert (sister != nil); + } + if (sister->left->color == dnode_black + && sister->right->color == dnode_black) { + sister->color = dnode_red; + child = parent; + } else { + if (sister->right->color == dnode_black) { + assert (sister->left->color == dnode_red); + sister->left->color = dnode_black; + sister->color = dnode_red; + rotate_right(dict, sister); + sister = parent->right; + assert (sister != nil); + } + sister->color = parent->color; + sister->right->color = dnode_black; + parent->color = dnode_black; + rotate_left(dict, parent); + break; + } + } else { /* symmetric case: child == child->parent->right */ + assert (child == parent->right); + sister = parent->left; + assert (sister != nil); + if (sister->color == dnode_red) { + sister->color = dnode_black; + parent->color = dnode_red; + rotate_right(dict, parent); + sister = parent->left; + assert (sister != nil); + } + if (sister->right->color == dnode_black + && sister->left->color == dnode_black) { + sister->color = dnode_red; + child = parent; + } else { + if (sister->left->color == dnode_black) { + assert (sister->right->color == dnode_red); + sister->right->color = dnode_black; + sister->color = dnode_red; + rotate_left(dict, sister); + sister = parent->left; + assert (sister != nil); + } + sister->color = parent->color; + sister->left->color = dnode_black; + parent->color = dnode_black; + rotate_right(dict, parent); + break; + } + } + } + + child->color = dnode_black; + dict_root(dict)->color = dnode_black; + } + + assert (dict_verify(dict)); + + return delete; +} + +/* + * Allocate a node using the dictionary's allocator routine, give it + * the data item. + */ + +int dict_alloc_insert(dict_t *dict, const void *key, void *data) +{ + dnode_t *node = dict->allocnode(dict->context); + + if (node) { + dnode_init(node, data); + dict_insert(dict, node, key); + return 1; + } + return 0; +} + +void dict_delete_free(dict_t *dict, dnode_t *node) +{ + dict_delete(dict, node); + dict->freenode(node, dict->context); +} + +/* + * Return the node with the lowest (leftmost) key. If the dictionary is empty + * (that is, dict_isempty(dict) returns 1) a null pointer is returned. + */ + +dnode_t *dict_first(dict_t *dict) +{ + dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left; + + if (root != nil) + while ((left = root->left) != nil) + root = left; + + return (root == nil) ? NULL : root; +} + +/* + * Return the node with the highest (rightmost) key. If the dictionary is empty + * (that is, dict_isempty(dict) returns 1) a null pointer is returned. + */ + +dnode_t *dict_last(dict_t *dict) +{ + dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *right; + + if (root != nil) + while ((right = root->right) != nil) + root = right; + + return (root == nil) ? NULL : root; +} + +/* + * Return the given node's successor node---the node which has the + * next key in the the left to right ordering. If the node has + * no successor, a null pointer is returned rather than a pointer to + * the nil node. + */ + +dnode_t *dict_next(dict_t *dict, dnode_t *curr) +{ + dnode_t *nil = dict_nil(dict), *parent, *left; + + if (curr->right != nil) { + curr = curr->right; + while ((left = curr->left) != nil) + curr = left; + return curr; + } + + parent = curr->parent; + + while (parent != nil && curr == parent->right) { + curr = parent; + parent = curr->parent; + } + + return (parent == nil) ? NULL : parent; +} + +/* + * Return the given node's predecessor, in the key order. + * The nil sentinel node is returned if there is no predecessor. + */ + +dnode_t *dict_prev(dict_t *dict, dnode_t *curr) +{ + dnode_t *nil = dict_nil(dict), *parent, *right; + + if (curr->left != nil) { + curr = curr->left; + while ((right = curr->right) != nil) + curr = right; + return curr; + } + + parent = curr->parent; + + while (parent != nil && curr == parent->left) { + curr = parent; + parent = curr->parent; + } + + return (parent == nil) ? NULL : parent; +} + +void dict_allow_dupes(dict_t *dict) +{ + dict->dupes = 1; +} + +#undef dict_count +#undef dict_isempty +#undef dict_isfull +#undef dnode_get +#undef dnode_put +#undef dnode_getkey + +dictcount_t dict_count(dict_t *dict) +{ + return dict->nodecount; +} + +int dict_isempty(dict_t *dict) +{ + return dict->nodecount == 0; +} + +int dict_isfull(dict_t *dict) +{ + return dict->nodecount == dict->maxcount; +} + +int dict_contains(dict_t *dict, dnode_t *node) +{ + return verify_dict_has_node(dict_nil(dict), dict_root(dict), node); +} + +static dnode_t *dnode_alloc(void *context) +{ + return malloc(sizeof *dnode_alloc(NULL)); +} + +static void dnode_free(dnode_t *node, void *context) +{ + free(node); +} + +dnode_t *dnode_create(void *data) +{ + dnode_t *new = malloc(sizeof *new); + if (new) { + new->data = data; + new->parent = NULL; + new->left = NULL; + new->right = NULL; + } + return new; +} + +dnode_t *dnode_init(dnode_t *dnode, void *data) +{ + dnode->data = data; + dnode->parent = NULL; + dnode->left = NULL; + dnode->right = NULL; + return dnode; +} + +void dnode_destroy(dnode_t *dnode) +{ + assert (!dnode_is_in_a_dict(dnode)); + free(dnode); +} + +void *dnode_get(dnode_t *dnode) +{ + return dnode->data; +} + +const void *dnode_getkey(dnode_t *dnode) +{ + return dnode->key; +} + +void dnode_put(dnode_t *dnode, void *data) +{ + dnode->data = data; +} + +int dnode_is_in_a_dict(dnode_t *dnode) +{ + return (dnode->parent && dnode->left && dnode->right); +} + +void dict_process(dict_t *dict, void *context, dnode_process_t function) +{ + dnode_t *node = dict_first(dict), *next; + + while (node != NULL) { + /* check for callback function deleting */ + /* the next node from under us */ + assert (dict_contains(dict, node)); + next = dict_next(dict, node); + function(dict, node, context); + node = next; + } + +} + + +#ifdef KAZLIB_TEST_MAIN + +#include +#include +#include +#include + +typedef char input_t[256]; + +static int tokenize(char *string, ...) +{ + char **tokptr; + va_list arglist; + int tokcount = 0; + + va_start(arglist, string); + tokptr = va_arg(arglist, char **); + while (tokptr) { + while (*string && isspace((unsigned char) *string)) + string++; + if (!*string) + break; + *tokptr = string; + while (*string && !isspace((unsigned char) *string)) + string++; + tokptr = va_arg(arglist, char **); + tokcount++; + if (!*string) + break; + *string++ = 0; + } + va_end(arglist); + + return tokcount; +} + +static int comparef(const void *key1, const void *key2) +{ + return strcmp(key1, key2); +} + +static char *dupstring(char *str) +{ + int sz = strlen(str) + 1; + char *new = malloc(sz); + if (new) + memcpy(new, str, sz); + return new; +} + +static dnode_t *new_node(void *c) +{ + static dnode_t few[5]; + static int count; + + if (count < 5) + return few + count++; + + return NULL; +} + +static void del_node(dnode_t *n, void *c) +{ +} + +int main(void) +{ + input_t in; + dict_t *d = dict_create(DICTCOUNT_T_MAX, comparef); + dnode_t *dn; + char *tok1, *tok2, *val; + const char *key; + int prompt = 0; + + char *help = + "a add value to dictionary\n" + "d delete value from dictionary\n" + "l lookup value in dictionary\n" + "( lookup lower bound\n" + ") lookup upper bound\n" + "k allow duplicate keys\n" + "c show number of entries\n" + "t dump whole dictionary in sort order\n" + "p turn prompt on\n" + "s switch to non-functioning allocator\n" + "q quit"; + + if (!d) + puts("dict_create failed"); + + for (;;) { + if (prompt) + putchar('>'); + fflush(stdout); + + if (!fgets(in, sizeof(input_t), stdin)) + break; + + switch(in[0]) { + case '?': + puts(help); + break; + case 'a': + if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) { + puts("what?"); + break; + } + key = dupstring(tok1); + val = dupstring(tok2); + + if (!key || !val) { + puts("out of memory"); + free((void *) key); + free(val); + } + + if (!dict_alloc_insert(d, key, val)) { + puts("dict_alloc_insert failed"); + free((void *) key); + free(val); + break; + } + break; + case 'd': + if (tokenize(in+1, &tok1, (char **) 0) != 1) { + puts("what?"); + break; + } + dn = dict_lookup(d, tok1); + if (!dn) { + puts("dict_lookup failed"); + break; + } + val = dnode_get(dn); + key = dnode_getkey(dn); + dict_delete_free(d, dn); + + free(val); + free((void *) key); + break; + case 'l': + case '(': + case ')': + if (tokenize(in+1, &tok1, (char **) 0) != 1) { + puts("what?"); + break; + } + dn = 0; + switch (in[0]) { + case 'l': + dn = dict_lookup(d, tok1); + break; + case '(': + dn = dict_lower_bound(d, tok1); + break; + case ')': + dn = dict_upper_bound(d, tok1); + break; + } + if (!dn) { + puts("lookup failed"); + break; + } + val = dnode_get(dn); + puts(val); + break; + case 'k': + dict_allow_dupes(d); + break; + case 'c': + printf("%lu\n", (unsigned long) dict_count(d)); + break; + case 't': + for (dn = dict_first(d); dn; dn = dict_next(d, dn)) { + printf("%s\t%s\n", (char *) dnode_getkey(dn), + (char *) dnode_get(dn)); + } + break; + case 'q': + exit(0); + break; + case '\0': + break; + case 'p': + prompt = 1; + break; + case 's': + dict_set_allocator(d, new_node, del_node, NULL); + break; + default: + putchar('?'); + putchar('\n'); + break; + } + } + + return 0; +} + +#endif diff --git a/dict.h b/dict.h new file mode 100644 index 0000000..3ac2e1a --- /dev/null +++ b/dict.h @@ -0,0 +1,128 @@ +/* + * Dictionary Abstract Data Type + * Copyright (C) 1997 Kaz Kylheku + * + * Free Software License: + * + * All rights are reserved by the author, with the following exceptions: + * Permission is granted to freely reproduce and distribute this software, + * possibly in exchange for a fee, provided that this copyright notice appears + * intact. Permission is also granted to adapt this software to produce + * derivative works, as long as the modified versions carry this copyright + * notice and additional notices stating that the work has been modified. + * This source code may be translated into executable form and incorporated + * into proprietary software; there is no requirement for such software to + * contain a copyright notice related to this source. + * + * $Id$ + * $Name: kazlib_1_15 $ + */ + +#ifndef DICT_H +#define DICT_H + +#include +#ifdef KAZLIB_SIDEEFFECT_DEBUG +#include "sfx.h" +#endif + +/* + * Blurb for inclusion into C++ translation units + */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned long dictcount_t; +#define DICTCOUNT_T_MAX ULONG_MAX + +/* + * The dictionary is implemented as a red-black tree + */ + +typedef enum { dnode_red, dnode_black } dnode_color_t; + +typedef struct dnode_t { + #if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) + struct dnode_t *dict_left; + struct dnode_t *dict_right; + struct dnode_t *dict_parent; + dnode_color_t dict_color; + const void *dict_key; + void *dict_data; + #else + int dict_dummy; + #endif +} dnode_t; + +typedef int (*dict_comp_t)(const void *, const void *); +typedef dnode_t *(*dnode_alloc_t)(void *); +typedef void (*dnode_free_t)(dnode_t *, void *); + +typedef struct dict_t { + #if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) + dnode_t dict_nilnode; + dictcount_t dict_nodecount; + dictcount_t dict_maxcount; + dict_comp_t dict_compare; + dnode_alloc_t dict_allocnode; + dnode_free_t dict_freenode; + void *dict_context; + int dict_dupes; + #else + int dict_dummmy; + #endif +} dict_t; + +typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *); + +extern dict_t *dict_create(dictcount_t, dict_comp_t); +extern void dict_set_allocator(dict_t *, dnode_alloc_t, dnode_free_t, void *); +extern void dict_destroy(dict_t *); +extern void dict_free(dict_t *); +extern dict_t *dict_init(dict_t *, dictcount_t, dict_comp_t); +extern int dict_verify(dict_t *); +extern dnode_t *dict_lookup(dict_t *, const void *); +extern dnode_t *dict_lower_bound(dict_t *, void *); +extern dnode_t *dict_upper_bound(dict_t *, void *); +extern void dict_insert(dict_t *, dnode_t *, const void *); +extern dnode_t *dict_delete(dict_t *, dnode_t *); +extern int dict_alloc_insert(dict_t *, const void *, void *); +extern void dict_delete_free(dict_t *, dnode_t *); +extern dnode_t *dict_first(dict_t *); +extern dnode_t *dict_last(dict_t *); +extern dnode_t *dict_next(dict_t *, dnode_t *); +extern dnode_t *dict_prev(dict_t *, dnode_t *); +extern dictcount_t dict_count(dict_t *); +extern int dict_isempty(dict_t *); +extern int dict_isfull(dict_t *); +extern int dict_contains(dict_t *, dnode_t *); +extern void dict_allow_dupes(dict_t *); +extern int dnode_is_in_a_dict(dnode_t *); +extern dnode_t *dnode_create(void *); +extern dnode_t *dnode_init(dnode_t *, void *); +extern void dnode_destroy(dnode_t *); +extern void *dnode_get(dnode_t *); +extern const void *dnode_getkey(dnode_t *); +extern void dnode_put(dnode_t *, void *); +extern void dict_process(dict_t *, void *, dnode_process_t); + +#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) +#ifdef KAZLIB_SIDEEFFECT_DEBUG +#define dict_isfull(D) (SFX_CHECK(D)->dict_nodecount == (D)->dict_maxcount) +#else +#define dict_isfull(D) ((D)->dict_nodecount == (D)->dict_maxcount) +#endif +#define dict_count(D) ((D)->dict_nodecount) +#define dict_isempty(D) ((D)->dict_nodecount == 0) +#define dnode_get(N) ((N)->dict_data) +#define dnode_getkey(N) ((N)->dict_key) +#define dnode_put(N, X) ((N)->dict_data = (X)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/dotconf.c b/dotconf.c new file mode 100644 index 0000000..e280eea --- /dev/null +++ b/dotconf.c @@ -0,0 +1,453 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** Code portions Borrowed from the dotconf libary. Header follows: +*/ + +/* dotconf + * Copyright (C) 1999 Lukas Schröder + * + * 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 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* +** NeoStats CVS Identification +** $Id$ +*/ + +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "defines.h" +#include "dotconf.h" + +static int word_count; /* no. of option arguments */ +static char name[CFG_MAX_OPTION + 1]; /* option name */ +static char values[CFG_VALUES][CFG_MAX_VALUE + 1]; /* holds the arguments */ +static char dotconf_includepath[CFG_MAX_FILENAME + 1]; + +char *dotconf_file; /* filename of current file */ +int dotconf_line = 0; /* line in file we are currently reading */ + +/* + * the list of config_options where a match for each name-token is + * searched for; i prefer the use of a fixed-size array, b/c special + * memory handling (malloc,free) would be necessary + */ +static config_option *config_options[CFG_MODULES]; + +/* + * some 'magic' options that are predefined by dot.conf itself for + * advanced functionality + */ +static void dotconf_cb_include (char *); /* magic 'Include' */ +static void dotconf_cb_includepath (char *); /* magic 'IncludePath' */ + +static config_option dotconf_options[] = { {"Include", ARG_STR, dotconf_cb_include, 0}, +{"IncludePath", ARG_STR, dotconf_cb_includepath, 0}, +LAST_OPTION +}; + +void +config_substitute_env (char *str) +{ + char *cp1, *cp2, *cp3, *eos, *eob; + char *env_value; + char env_name[CFG_MAX_VALUE + 1]; + char env_default[CFG_MAX_VALUE + 1]; + char tmp_value[CFG_MAX_VALUE + 1]; + + bzero (env_name, CFG_MAX_VALUE + 1); + bzero (env_default, CFG_MAX_VALUE + 1); + bzero (tmp_value, CFG_MAX_VALUE + 1); + cp1 = str; + eob = cp1 + CFG_MAX_VALUE + 1; + cp2 = tmp_value; + eos = cp2 + CFG_MAX_VALUE + 1; + + while ((cp1 != eos) && (cp2 != eos) && (*cp1 != '\0')) { + /* substitution needed ?? */ + if (*cp1 == '$' && *(cp1 + 1) == '{') { + /* yeah */ + cp1 += 2; /* skip ${ */ + cp3 = env_name; + while ((cp1 != eos) + && !(*cp1 == '}' || *cp1 == ':')) + *cp3++ = *cp1++; + *cp3 = '\0'; /* terminate */ + + /* default substitution */ + if (*cp1 == ':' && *(cp1 + 1) == '-') { + cp1 += 2; /* skip :- */ + cp3 = env_default; + while ((cp1 != eos) && (*cp1 != '}')) + *cp3++ = *cp1++; + *cp3 = '\0'; /* terminate */ + } else + while ((cp1 != eos) && (*cp1 != '}')) + cp1++; + + if (*cp1 != '}') + fprintf (stderr, "%s:%d: Unbalanced '{'\n", dotconf_file, dotconf_line); + else { + cp1++; /* skip } */ + if ((env_value = getenv (env_name)) != NULL) { + strncat (cp2, env_value, eos - cp2); + cp2 += strlen (env_value); + } else { + strncat (cp2, env_default, eos - cp2); + cp2 += strlen (env_default); + } + } + + } + + *cp2++ = *cp1++; + } + *cp2 = '\0'; /* terminate buffer */ + + strncpy (str, tmp_value, CFG_MAX_VALUE + 1); +} + +void +config_register_options (config_option * options) +{ + int i; + for (i = 0; i < CFG_MODULES && config_options[i]; i++) { + } + config_options[i] = options; +} + +int +config_parse (FILE * config) +{ + static char buffer[CFG_BUFSIZE]; + static char *here_string; /* Damn FreeBSD */ + static char *here_limit; + static char *here_doc; + + while ((fgets (buffer, CFG_BUFSIZE, config)) != NULL) { /* for each line */ + char *cp1, *cp2; /* generic char pointer */ + char *eob, *eos; /* end of buffer; end of string */ + char sq, dq; /* state flags: single/double quote */ + int i, mod; /* generic counter, mod holds the module index */ + config_option opt; /* matched option from config_options */ + + dotconf_line++; + + /* ignore #-comments and empty lines */ + if ((buffer[0] == '#' || buffer[0] == '\n')) + continue; + + /* clear fields */ + word_count = 0; + name[0] = 0; + for (i = 0; i < CFG_VALUES; i++) + values[i][0] = 0; + + /* initialize char pointer */ + cp1 = buffer; + eob = cp1 + strlen (cp1); /* calculate end of buffer */ + + /* skip any whitspace of indented lines */ + while ((cp1 != eob) && (isspace (*cp1))) + cp1++; + /* skip line if it only contains whitespace */ + if (cp1 == eob) + continue; + + /* get first token: read the name of a possible option */ + cp2 = name; + while ((*cp1 != '\0') && (!isspace (*cp1))) + *cp2++ = *cp1++; + *cp2 = '\0'; + + /* and now find the entry in the option table, and call the callback */ + bzero (&opt, sizeof (config_option)); + for (mod = 0; mod < CFG_MODULES && config_options[mod]; mod++) + for (i = 0; config_options[mod][i].name[0]; i++) + if (!strncmp (name, config_options[mod][i].name, CFG_MAX_OPTION)) { + opt = config_options[mod][i]; + break; /* found it; break out of for */ + } + + if (opt.name[0] == 0) { + /* cannot find it + fprintf(stderr, "Unknown Config-Option: '%s' in %s:%d\n", + name, dotconf_file, dotconf_line); + continue; move on to the next line immediately */ + } else if (opt.type == ARG_RAW) { + /* if it is an ARG_RAW type, save some time and call the + callback now */ + opt.callback (cp1, opt.userdata); + continue; + } else if (opt.type == ARG_STR) { + /* check if it's a here-document and act accordingly */ + char *cp3 = cp1; + + bzero (&here_limit, 9); + + /* skip whitespace */ + while ((cp3 < eob) && (*cp3 != '\0') + && (isspace (*cp3))) + cp3++; + + if (!strncmp ("<<", cp3, 2)) { /* here string sign */ + /* it's a here-document: yeah, what a cool feature ;) */ + struct stat finfo; + + stat (dotconf_file, &finfo); + /* + * allocate a buffer of filesize bytes; should be enough to + * prevent buffer overflows + */ + here_doc = malloc (finfo.st_size + 1); /* allocate buffer memory */ + bzero (here_doc, finfo.st_size + 1); + + strncpy (here_limit, cp3 + 2, 8); /* copy here-delimiter */ + while (fgets (buffer, CFG_BUFSIZE, config)) { + if (!strncmp (here_limit, buffer, strlen (here_limit))) { + here_string = 0; + break; + } + strcat (here_doc, buffer); /* append to buffer */ + } + if (here_string) + fprintf (stderr, "Line %d: Unterminated here-document!\n", dotconf_line); + here_doc[strlen (here_doc) - 1] = '\0'; /* strip newline */ + opt.callback (here_doc, opt.userdata); /* call back */ + + free (here_doc); /* free buffer memory */ + + continue; + } + + } + + free (here_doc); + /* skip whitespace */ + while ((cp1 < eob) && (*cp1 != '\0') && (isspace (*cp1))) + cp1++; + + /* start reading option arguments */ + cp2 = values[word_count]; + eos = cp2 + CFG_MAX_VALUE - 1; + sq = 0; + dq = 0; /* clear quoting flags */ + while ((*cp1 != '\0') && (cp2 != eos) + && (word_count < CFG_VALUES)) { + switch (*cp1) { + case '\'': /* single quote */ + if (dq) + break; /* already double quoting, break out */ + if (sq) { + sq--; + } /* already single quoting, clear state */ + else if (!sq) { + sq++; + } /* set state for single quoting */ + break; + case '"': /* double quote */ + if (sq) + break; /* already single quoting, break out */ + if (dq) { + dq--; + } /* already double quoting, clear state */ + else if (!dq) { + dq++; + } /* set state for double quoting */ + break; + default: + break; + } + /* unquoted space: start a new option argument */ + if (isspace (*cp1) && !dq && !sq) { + *cp2 = '\0'; /* terminate current argument */ + /* increment word counter and update char pointer */ + cp2 = values[++word_count]; + /* skip all whitespace between 2 arguments */ + while (isspace (*(cp1 + 1)) + && (*cp1 != '\0')) + cp1++; + } + /* not space or quoted ; eat it: */ + else if ((((!isspace (*cp1) && !dq && !sq && *cp1 != '"' && *cp1 != '\'') + /* dont take quote if quoting: */ + || (dq && (*cp1 != '"')) + || (sq && *cp1 != '\'')))) + *cp2++ = *cp1; + cp1++; + } + + if (opt.name[0] > 32) { /* has an option entry been found before? */ + /* found it, now check the type of args it wants */ +#define USER_DATA opt.userdata + switch (opt.type) { + case ARG_TOGGLE: + { + /* the value is true if the argument is Yes, On or 1 */ + /* kludge code follows ;) */ + int arg = ((values[0][0] == 'Y' || values[0][1] == 'y') + || (values[0][0] == '1') + || ((values[0][0] == 'o' || values[0][0] == 'O') + && (values[0][1] == 'n' || values[0][1] + == 'N'))); + opt.callback (arg, USER_DATA); + break; + } + case ARG_INT: + { + int arg = atoi (values[0]); + opt.callback (arg, USER_DATA); + break; + } + case ARG_STR: + { + config_substitute_env (values[0]); + opt.callback (values[0], USER_DATA); + break; + } + case ARG_LIST: + { + char *data[CFG_VALUES]; + int i; + for (i = 0; i < word_count; i++) { /* prepare list */ + config_substitute_env (values[i]); + data[i] = strdup (values[i]); + } + opt.callback (data, word_count, USER_DATA); + + for (i = 0; i < word_count; i++) /* dump list */ + free (data[i]); + + break; + } + case ARG_NONE: + { + opt.callback (); + break; + } + case ARG_RAW: /* this has been handled before */ + default: + { + break; + } + } + } + } + return -1; +} + +/* + * open and parse the config-file using the config_options list + * as reference for what callback to call and what type of arguments to provide + */ +int +config_read (char *fname, config_option * options) +{ + FILE *config; + char *dc_env; /* pointer to DC_INCLUDEPATH */ + + if (access (fname, R_OK)) { + fprintf (stderr, "Error opening configuration file '%s'\n", fname); + return 1; + } + + dotconf_file = malloc (CFG_MAX_FILENAME + 1); /* allocate fname buffer */ + bzero (dotconf_file, CFG_MAX_FILENAME + 1); + bzero (dotconf_includepath, CFG_MAX_FILENAME + 1); + + strncpy (dotconf_file, fname, CFG_MAX_FILENAME); /* fill fname buffer */ + + /* take includepath from environment if present */ + if ((dc_env = getenv (CFG_INCLUDEPATH_ENV)) != NULL) + strncpy (dotconf_includepath, dc_env, CFG_MAX_FILENAME); + + config_register_options (dotconf_options); /* internal options */ + config_register_options (options); /* register main options */ + + config = fopen (dotconf_file, "r"); + config_parse (config); /* fire off parser */ + fclose (config); + + free (dotconf_file); /* free fname buffer */ + + return 0; +} + +/* callbacks for internal options */ + +void +dotconf_cb_include (char *str) +{ + FILE *config; + char old_fname[CFG_MAX_FILENAME]; + + bzero (&old_fname, CFG_MAX_FILENAME); + strncpy (old_fname, dotconf_file, CFG_MAX_FILENAME); + if (str[0] != '/' && dotconf_includepath[0] != '\0') { + /* relative file AND include path is used */ + + /* check for length of fully qualified filename */ + if ((strlen (str) + strlen (dotconf_includepath) + 1) == CFG_MAX_FILENAME) { + fprintf (stderr, "%s:%d: Absolute filename too long (>%d)\n", dotconf_file, dotconf_line, CFG_MAX_FILENAME); + return; + } + + snprintf (dotconf_file, CFG_MAX_FILENAME + 1, "%s/%s", dotconf_includepath, str); + } else /* fully qualified, or no includepath */ + strncpy (dotconf_file, str, CFG_MAX_FILENAME); + + if (access (dotconf_file, R_OK)) { + fprintf (stderr, "Error in %s line %d: Cannot open %s for inclusion\n", old_fname, dotconf_line, dotconf_file); + strncpy (dotconf_file, old_fname, CFG_MAX_FILENAME); /* restore settings */ + return; + } + + config = fopen (dotconf_file, "r"); + config_parse (config); + fclose (config); + strncpy (dotconf_file, old_fname, CFG_MAX_FILENAME); +} + +void +dotconf_cb_includepath (char *str) +{ + char *env = getenv ("DC_INCLUDEPATH"); + if (!env) /* environment overrides configuration file setting */ + strncpy (dotconf_includepath, str, CFG_MAX_FILENAME); +} diff --git a/dotconf.h b/dotconf.h new file mode 100644 index 0000000..2003a77 --- /dev/null +++ b/dotconf.h @@ -0,0 +1,81 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + + +#ifndef HAVE_CFG_H +#define HAVE_CFG_H + +/* some buffersize definitions */ +#define CFG_BUFSIZE 4096 /* max length of one line */ +#define CFG_MAX_OPTION 32 /* max length of any option name */ +#define CFG_MAX_VALUE 4064 /* max length of any options value */ +#define CFG_MAX_FILENAME 256 /* max length of a filename */ +#define CFG_VALUES 16 /* max # of arguments an option takes */ +#define CFG_MODULES 64 /* max # of dynamically loadable modules */ + +#define CFG_INCLUDEPATH_ENV "DC_INCLUDEPATH" + +/* constants for type of option */ +#define ARG_TOGGLE 0 /* TOGGLE on,off; yes,no; 1, 0; */ +#define ARG_INT 1 /* callback wants an integer */ +#define ARG_STR 2 /* callback expects a \0 terminated str */ +#define ARG_LIST 3 /* wants list of strings */ +#define ARG_NAME 4 /* wants option name */ +#define ARG_RAW 5 /* wants raw argument data */ +#define ARG_NONE 6 /* does not expect ANY args */ + +/* for convenience of terminating the config_options list */ +#define LAST_OPTION { "", 0, NULL, 0 } + +typedef struct _cfgoption { + char name[CFG_MAX_OPTION]; /* name of configuration option */ + int type; /* for possible values, see above */ + void (*callback) (); /* callback function */ + int userdata; /* userdefinable value/flag */ +} config_option; + +/* general configuration items */ +struct config { + /* debug level */ + unsigned int debug; + /* enable recv.log */ + unsigned int recvlog:1; + /* dont load modules on startup */ + unsigned int modnoload:1; + /* dont output anything on start */ + unsigned int quiet:1; + /* dont detach into background */ + unsigned int foreground:1; +} config; + +/* config_read takes the following arguments: + * 1. the filename of the configuration file to read + * 2. the list of optionnames to recognize + * + * returns 0 on success; !0 on error */ +int config_read (char *, config_option *); +void config_register_options (config_option *); + +#endif /* HAVE_CFG_H */ diff --git a/hash.c b/hash.c new file mode 100644 index 0000000..e8bdfab --- /dev/null +++ b/hash.c @@ -0,0 +1,898 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** Code portions borrowed from kazlib. Header Follows: +*/ + + +/* + * Hash Table Data Type + * Copyright (C) 1997 Kaz Kylheku + * + * Free Software License: + * + * All rights are reserved by the author, with the following exceptions: + * Permission is granted to freely reproduce and distribute this software, + * possibly in exchange for a fee, provided that this copyright notice appears + * intact. Permission is also granted to adapt this software to produce + * derivative works, as long as the modified versions carry this copyright + * notice and additional notices stating that the work has been modified. + * This source code may be translated into executable form and incorporated + * into proprietary software; there is no requirement for such software to + * contain a copyright notice related to this source. + * + * $Id$ + * $Name: $ + */ + +#include +#include +#include +#include +#include +#define HASH_IMPLEMENTATION +#include "hash.h" +#include "log.h" + +#ifdef KAZLIB_RCSID +static const char rcsid[] = "$Id$"; +#endif + +#define INIT_BITS 6 +#define INIT_SIZE (1UL << (INIT_BITS)) /* must be power of two */ +#define INIT_MASK ((INIT_SIZE) - 1) + +#define next hash_next +#define key hash_key +#define data hash_data +#define hkey hash_hkey + +#define table hash_table +#define nchains hash_nchains +#define nodecount hash_nodecount +#define maxcount hash_maxcount +#define highmark hash_highmark +#define lowmark hash_lowmark +#define compare hash_compare +#define function hash_function +#define allocnode hash_allocnode +#define freenode hash_freenode +#define context hash_context +#define mask hash_mask +#define dynamic hash_dynamic + +#define table hash_table +#define chain hash_chain + +static hnode_t *hnode_alloc (void *context); +static void hnode_free (hnode_t * node, void *context); +static hash_val_t hash_fun_default (const void *key); +static int hash_comp_default (const void *key1, const void *key2); + +int hash_val_t_bit; + +/* + * Compute the number of bits in the hash_val_t type. We know that hash_val_t + * is an unsigned integral type. Thus the highest value it can hold is a + * Mersenne number (power of two, less one). We initialize a hash_val_t + * object with this value and then shift bits out one by one while counting. + * Notes: + * 1. HASH_VAL_T_MAX is a Mersenne number---one that is one less than a power + * of two. This means that its binary representation consists of all one + * bits, and hence ``val'' is initialized to all one bits. + * 2. While bits remain in val, we increment the bit count and shift it to the + * right, replacing the topmost bit by zero. + */ + +static void +compute_bits (void) +{ + hash_val_t val = HASH_VAL_T_MAX; /* 1 */ + int bits = 0; + + while (val) { /* 2 */ + bits++; + val >>= 1; + } + + hash_val_t_bit = bits; +} + +/* + * Verify whether the given argument is a power of two. + */ + +static int +is_power_of_two (hash_val_t arg) +{ + if (arg == 0) + return 0; + while ((arg & 1) == 0) + arg >>= 1; + return (arg == 1); +} + +/* + * Compute a shift amount from a given table size + */ + +static hash_val_t +compute_mask (hashcount_t size) +{ + nassert (is_power_of_two (size)); + nassert (size >= 2); + + return size - 1; +} + +/* + * Initialize the table of pointers to null. + */ + +static void +clear_table (hash_t * hash) +{ + hash_val_t i; + + for (i = 0; i < hash->nchains; i++) + hash->table[i] = NULL; +} + +/* + * Double the size of a dynamic table. This works as follows. Each chain splits + * into two adjacent chains. The shift amount increases by one, exposing an + * additional bit of each hashed key. For each node in the original chain, the + * value of this newly exposed bit will decide which of the two new chains will + * receive the node: if the bit is 1, the chain with the higher index will have + * the node, otherwise the lower chain will receive the node. In this manner, + * the hash table will continue to function exactly as before without having to + * rehash any of the keys. + * Notes: + * 1. Overflow check. + * 2. The new number of chains is twice the old number of chains. + * 3. The new mask is one bit wider than the previous, revealing a + * new bit in all hashed keys. + * 4. Allocate a new table of chain pointers that is twice as large as the + * previous one. + * 5. If the reallocation was successful, we perform the rest of the growth + * algorithm, otherwise we do nothing. + * 6. The exposed_bit variable holds a mask with which each hashed key can be + * AND-ed to test the value of its newly exposed bit. + * 7. Now loop over each chain in the table and sort its nodes into two + * chains based on the value of each node's newly exposed hash bit. + * 8. The low chain replaces the current chain. The high chain goes + * into the corresponding sister chain in the upper half of the table. + * 9. We have finished dealing with the chains and nodes. We now update + * the various bookeeping fields of the hash structure. + */ + +static void +grow_table (hash_t * hash) +{ + hnode_t **newtable; + + nassert (2 * hash->nchains > hash->nchains); /* 1 */ + + newtable = realloc (hash->table, sizeof *newtable * hash->nchains * 2); /* 4 */ + + if (newtable) { /* 5 */ + hash_val_t mask = (hash->mask << 1) | 1; /* 3 */ + hash_val_t exposed_bit = mask ^ hash->mask; /* 6 */ + hash_val_t chain; + + nassert (mask != hash->mask); + + for (chain = 0; chain < hash->nchains; chain++) { /* 7 */ + hnode_t *low_chain = 0, *high_chain = 0, *hptr, *next; + + for (hptr = newtable[chain]; hptr != 0; hptr = next) { + next = hptr->next; + + if (hptr->hkey & exposed_bit) { + hptr->next = high_chain; + high_chain = hptr; + } else { + hptr->next = low_chain; + low_chain = hptr; + } + } + + newtable[chain] = low_chain; /* 8 */ + newtable[chain + hash->nchains] = high_chain; + } + + hash->table = newtable; /* 9 */ + hash->mask = mask; + hash->nchains *= 2; + hash->lowmark *= 2; + hash->highmark *= 2; + } + nassert (hash_verify (hash)); +} + +/* + * Cut a table size in half. This is done by folding together adjacent chains + * and populating the lower half of the table with these chains. The chains are + * simply spliced together. Once this is done, the whole table is reallocated + * to a smaller object. + * Notes: + * 1. It is illegal to have a hash table with one slot. This would mean that + * hash->shift is equal to hash_val_t_bit, an illegal shift value. + * Also, other things could go wrong, such as hash->lowmark becoming zero. + * 2. Looping over each pair of sister chains, the low_chain is set to + * point to the head node of the chain in the lower half of the table, + * and high_chain points to the head node of the sister in the upper half. + * 3. The intent here is to compute a pointer to the last node of the + * lower chain into the low_tail variable. If this chain is empty, + * low_tail ends up with a null value. + * 4. If the lower chain is not empty, we simply tack the upper chain onto it. + * If the upper chain is a null pointer, nothing happens. + * 5. Otherwise if the lower chain is empty but the upper one is not, + * If the low chain is empty, but the high chain is not, then the + * high chain is simply transferred to the lower half of the table. + * 6. Otherwise if both chains are empty, there is nothing to do. + * 7. All the chain pointers are in the lower half of the table now, so + * we reallocate it to a smaller object. This, of course, invalidates + * all pointer-to-pointers which reference into the table from the + * first node of each chain. + * 8. Though it's unlikely, the reallocation may fail. In this case we + * pretend that the table _was_ reallocated to a smaller object. + * 9. Finally, update the various table parameters to reflect the new size. + */ + +static void +shrink_table (hash_t * hash) +{ + hash_val_t chain, nchains; + hnode_t **newtable, *low_tail, *low_chain, *high_chain; + + nassert (hash->nchains >= 2); /* 1 */ + nchains = hash->nchains / 2; + + for (chain = 0; chain < nchains; chain++) { + low_chain = hash->table[chain]; /* 2 */ + high_chain = hash->table[chain + nchains]; + for (low_tail = low_chain; low_tail && low_tail->next; low_tail = low_tail->next); /* 3 */ + if (low_chain != 0) /* 4 */ + low_tail->next = high_chain; + else if (high_chain != 0) /* 5 */ + hash->table[chain] = high_chain; + else + nassert (hash->table[chain] == NULL); /* 6 */ + } + newtable = realloc (hash->table, sizeof *newtable * nchains); /* 7 */ + if (newtable) /* 8 */ + hash->table = newtable; + hash->mask >>= 1; /* 9 */ + hash->nchains = nchains; + hash->lowmark /= 2; + hash->highmark /= 2; + nassert (hash_verify (hash)); +} + + +/* + * Create a dynamic hash table. Both the hash table structure and the table + * itself are dynamically allocated. Furthermore, the table is extendible in + * that it will automatically grow as its load factor increases beyond a + * certain threshold. + * Notes: + * 1. If the number of bits in the hash_val_t type has not been computed yet, + * we do so here, because this is likely to be the first function that the + * user calls. + * 2. Allocate a hash table control structure. + * 3. If a hash table control structure is successfully allocated, we + * proceed to initialize it. Otherwise we return a null pointer. + * 4. We try to allocate the table of hash chains. + * 5. If we were able to allocate the hash chain table, we can finish + * initializing the hash structure and the table. Otherwise, we must + * backtrack by freeing the hash structure. + * 6. INIT_SIZE should be a power of two. The high and low marks are always set + * to be twice the table size and half the table size respectively. When the + * number of nodes in the table grows beyond the high size (beyond load + * factor 2), it will double in size to cut the load factor down to about + * about 1. If the table shrinks down to or beneath load factor 0.5, + * it will shrink, bringing the load up to about 1. However, the table + * will never shrink beneath INIT_SIZE even if it's emptied. + * 7. This indicates that the table is dynamically allocated and dynamically + * resized on the fly. A table that has this value set to zero is + * assumed to be statically allocated and will not be resized. + * 8. The table of chains must be properly reset to all null pointers. + */ + +hash_t * +hash_create (hashcount_t maxcount, hash_comp_t compfun, hash_fun_t hashfun) +{ + hash_t *hash; + + if (hash_val_t_bit == 0) /* 1 */ + compute_bits (); + + hash = malloc (sizeof *hash); /* 2 */ + + if (hash) { /* 3 */ + hash->table = malloc (sizeof *hash->table * INIT_SIZE); /* 4 */ + if (hash->table) { /* 5 */ + hash->nchains = INIT_SIZE; /* 6 */ + hash->highmark = INIT_SIZE * 2; + hash->lowmark = INIT_SIZE / 2; + hash->nodecount = 0; + hash->maxcount = maxcount; + hash->compare = compfun ? compfun : hash_comp_default; + hash->function = hashfun ? hashfun : hash_fun_default; + hash->allocnode = hnode_alloc; + hash->freenode = hnode_free; + hash->context = NULL; + hash->mask = INIT_MASK; + hash->dynamic = 1; /* 7 */ + clear_table (hash); /* 8 */ + nassert (hash_verify (hash)); + return hash; + } + free (hash); + } + + return NULL; +} + +/* + * Select a different set of node allocator routines. + */ + +void +hash_set_allocator (hash_t * hash, hnode_alloc_t al, hnode_free_t fr, void *context) +{ + nassert (hash_count (hash) == 0); + nassert ((al == 0 && fr == 0) || (al != 0 && fr != 0)); + + hash->allocnode = al ? al : hnode_alloc; + hash->freenode = fr ? fr : hnode_free; + hash->context = context; +} + +/* + * Free every node in the hash using the hash->freenode() function pointer, and + * cause the hash to become empty. + */ + +void +hash_free_nodes (hash_t * hash) +{ + hscan_t hs; + hnode_t *node; + hash_scan_begin (&hs, hash); + while ((node = hash_scan_next (&hs))) { + hash_scan_delete (hash, node); + hash->freenode (node, hash->context); + } + hash->nodecount = 0; + clear_table (hash); +} + +/* + * Obsolescent function for removing all nodes from a table, + * freeing them and then freeing the table all in one step. + */ + +void +hash_free (hash_t * hash) +{ +#ifdef KAZLIB_OBSOLESCENT_DEBUG + nassert ("call to obsolescent function hash_free()" && 0); +#endif + hash_free_nodes (hash); + hash_destroy (hash); +} + +/* + * Free a dynamic hash table structure. + */ + +void +hash_destroy (hash_t * hash) +{ + nassert (hash_val_t_bit != 0); + nassert (hash_isempty (hash)); + free (hash->table); + free (hash); +} + +/* + * Initialize a user supplied hash structure. The user also supplies a table of + * chains which is assigned to the hash structure. The table is static---it + * will not grow or shrink. + * 1. See note 1. in hash_create(). + * 2. The user supplied array of pointers hopefully contains nchains nodes. + * 3. See note 7. in hash_create(). + * 4. We must dynamically compute the mask from the given power of two table + * size. + * 5. The user supplied table can't be assumed to contain null pointers, + * so we reset it here. + */ + +hash_t * +hash_init (hash_t * hash, hashcount_t maxcount, hash_comp_t compfun, hash_fun_t hashfun, hnode_t ** table, hashcount_t nchains) +{ + if (hash_val_t_bit == 0) /* 1 */ + compute_bits (); + + nassert (is_power_of_two (nchains)); + + hash->table = table; /* 2 */ + hash->nchains = nchains; + hash->nodecount = 0; + hash->maxcount = maxcount; + hash->compare = compfun ? compfun : hash_comp_default; + hash->function = hashfun ? hashfun : hash_fun_default; + hash->dynamic = 0; /* 3 */ + hash->mask = compute_mask (nchains); /* 4 */ + clear_table (hash); /* 5 */ + + nassert (hash_verify (hash)); + + return hash; +} + +/* + * Reset the hash scanner so that the next element retrieved by + * hash_scan_next() shall be the first element on the first non-empty chain. + * Notes: + * 1. Locate the first non empty chain. + * 2. If an empty chain is found, remember which one it is and set the next + * pointer to refer to its first element. + * 3. Otherwise if a chain is not found, set the next pointer to NULL + * so that hash_scan_next() shall indicate failure. + */ + +void +hash_scan_begin (hscan_t * scan, hash_t * hash) +{ + hash_val_t nchains = hash->nchains; + hash_val_t chain; + + scan->table = hash; + + /* 1 */ + + for (chain = 0; chain < nchains && hash->table[chain] == 0; chain++); + + if (chain < nchains) { /* 2 */ + scan->chain = chain; + scan->next = hash->table[chain]; + } else { /* 3 */ + scan->next = NULL; + } +} + +/* + * Retrieve the next node from the hash table, and update the pointer + * for the next invocation of hash_scan_next(). + * Notes: + * 1. Remember the next pointer in a temporary value so that it can be + * returned. + * 2. This nassertion essentially checks whether the module has been properly + * initialized. The first point of interaction with the module should be + * either hash_create() or hash_init(), both of which set hash_val_t_bit to + * a non zero value. + * 3. If the next pointer we are returning is not NULL, then the user is + * allowed to call hash_scan_next() again. We prepare the new next pointer + * for that call right now. That way the user is allowed to delete the node + * we are about to return, since we will no longer be needing it to locate + * the next node. + * 4. If there is a next node in the chain (next->next), then that becomes the + * new next node, otherwise ... + * 5. We have exhausted the current chain, and must locate the next subsequent + * non-empty chain in the table. + * 6. If a non-empty chain is found, the first element of that chain becomes + * the new next node. Otherwise there is no new next node and we set the + * pointer to NULL so that the next time hash_scan_next() is called, a null + * pointer shall be immediately returned. + */ + + +hnode_t * +hash_scan_next (hscan_t * scan) +{ + hnode_t *next = scan->next; /* 1 */ + hash_t *hash = scan->table; + hash_val_t chain = scan->chain + 1; + hash_val_t nchains = hash->nchains; + + nassert (hash_val_t_bit != 0); /* 2 */ + + if (next) { /* 3 */ + if (next->next) { /* 4 */ + scan->next = next->next; + } else { + while (chain < nchains && hash->table[chain] == 0) /* 5 */ + chain++; + if (chain < nchains) { /* 6 */ + scan->chain = chain; + scan->next = hash->table[chain]; + } else { + scan->next = NULL; + } + } + } + return next; +} + +/* + * Insert a node into the hash table. + * Notes: + * 1. It's illegal to insert more than the maximum number of nodes. The client + * should verify that the hash table is not full before attempting an + * insertion. + * 2. The same key may not be inserted into a table twice. + * 3. If the table is dynamic and the load factor is already at >= 2, + * grow the table. + * 4. We take the bottom N bits of the hash value to derive the chain index, + * where N is the base 2 logarithm of the size of the hash table. + */ + +void +hash_insert (hash_t * hash, hnode_t * node, const void *key) +{ + hash_val_t hkey, chain; + + nassert (hash_val_t_bit != 0); + nassert (node->next == NULL); + nassert (hash->nodecount < hash->maxcount); /* 1 */ + nassert (hash_lookup (hash, key) == NULL); /* 2 */ + + if (hash->dynamic && hash->nodecount >= hash->highmark) /* 3 */ + grow_table (hash); + + hkey = hash->function (key); + chain = hkey & hash->mask; /* 4 */ + + node->key = key; + node->hkey = hkey; + node->next = hash->table[chain]; + hash->table[chain] = node; + hash->nodecount++; + + nassert (hash_verify (hash)); +} + +/* + * Find a node in the hash table and return a pointer to it. + * Notes: + * 1. We hash the key and keep the entire hash value. As an optimization, when + * we descend down the chain, we can compare hash values first and only if + * hash values match do we perform a full key comparison. + * 2. To locate the chain from among 2^N chains, we look at the lower N bits of + * the hash value by anding them with the current mask. + * 3. Looping through the chain, we compare the stored hash value inside each + * node against our computed hash. If they match, then we do a full + * comparison between the unhashed keys. If these match, we have located the + * entry. + */ + +hnode_t * +hash_lookup (hash_t * hash, const void *key) +{ + hash_val_t hkey, chain; + hnode_t *nptr; + + hkey = hash->function (key); /* 1 */ + chain = hkey & hash->mask; /* 2 */ + + for (nptr = hash->table[chain]; nptr; nptr = nptr->next) { /* 3 */ + if (nptr->hkey == hkey && hash->compare (nptr->key, key) == 0) + return nptr; + } + + return NULL; +} + +/* + * Delete the given node from the hash table. Since the chains + * are singly linked, we must locate the start of the node's chain + * and traverse. + * Notes: + * 1. The node must belong to this hash table, and its key must not have + * been tampered with. + * 2. If this deletion will take the node count below the low mark, we + * shrink the table now. + * 3. Determine which chain the node belongs to, and fetch the pointer + * to the first node in this chain. + * 4. If the node being deleted is the first node in the chain, then + * simply update the chain head pointer. + * 5. Otherwise advance to the node's predecessor, and splice out + * by updating the predecessor's next pointer. + * 6. Indicate that the node is no longer in a hash table. + */ + +hnode_t * +hash_delete (hash_t * hash, hnode_t * node) +{ + hash_val_t chain; + hnode_t *hptr; + + nassert (hash_lookup (hash, node->key) == node); /* 1 */ + nassert (hash_val_t_bit != 0); + + if (hash->dynamic && hash->nodecount <= hash->lowmark && hash->nodecount > INIT_SIZE) + shrink_table (hash); /* 2 */ + + chain = node->hkey & hash->mask; /* 3 */ + hptr = hash->table[chain]; + + if (hptr == node) { /* 4 */ + hash->table[chain] = node->next; + } else { + while (hptr->next != node) { /* 5 */ + nassert (hptr != 0); + hptr = hptr->next; + } + nassert (hptr->next == node); + hptr->next = node->next; + } + + hash->nodecount--; + nassert (hash_verify (hash)); + + node->next = NULL; /* 6 */ + return node; +} + +int +hash_alloc_insert (hash_t * hash, const void *key, void *data) +{ + hnode_t *node = hash->allocnode (hash->context); + + if (node) { + hnode_init (node, data); + hash_insert (hash, node, key); + return 1; + } + return 0; +} + +void +hash_delete_free (hash_t * hash, hnode_t * node) +{ + hash_delete (hash, node); + hash->freenode (node, hash->context); +} + +/* + * Exactly like hash_delete, except does not trigger table shrinkage. This is to be + * used from within a hash table scan operation. See notes for hash_delete. + */ + +hnode_t * +hash_scan_delete (hash_t * hash, hnode_t * node) +{ + hash_val_t chain; + hnode_t *hptr; + + nassert (hash_lookup (hash, node->key) == node); + nassert (hash_val_t_bit != 0); + + chain = node->hkey & hash->mask; + hptr = hash->table[chain]; + + if (hptr == node) { + hash->table[chain] = node->next; + } else { + while (hptr->next != node) + hptr = hptr->next; + hptr->next = node->next; + } + + hash->nodecount--; + nassert (hash_verify (hash)); + node->next = NULL; + + return node; +} + +/* + * Like hash_delete_free but based on hash_scan_delete. + */ + +void +hash_scan_delfree (hash_t * hash, hnode_t * node) +{ + hash_scan_delete (hash, node); + hash->freenode (node, hash->context); +} + +/* + * Verify whether the given object is a valid hash table. This means + * Notes: + * 1. If the hash table is dynamic, verify whether the high and + * low expansion/shrinkage thresholds are powers of two. + * 2. Count all nodes in the table, and test each hash value + * to see whether it is correct for the node's chain. + */ + +int +hash_verify (hash_t * hash) +{ + hashcount_t count = 0; + hash_val_t chain; + hnode_t *hptr; + + if (hash->dynamic) { /* 1 */ + if (hash->lowmark >= hash->highmark) + return 0; + if (!is_power_of_two (hash->highmark)) + return 0; + if (!is_power_of_two (hash->lowmark)) + return 0; + } + + for (chain = 0; chain < hash->nchains; chain++) { /* 2 */ + for (hptr = hash->table[chain]; hptr != 0; hptr = hptr->next) { + if ((hptr->hkey & hash->mask) != chain) + return 0; + count++; + } + } + + if (count != hash->nodecount) + return 0; + + return 1; +} + +/* + * Test whether the hash table is full and return 1 if this is true, + * 0 if it is false. + */ + +#undef hash_isfull +int +hash_isfull (hash_t * hash) +{ + return hash->nodecount == hash->maxcount; +} + +/* + * Test whether the hash table is empty and return 1 if this is true, + * 0 if it is false. + */ + +#undef hash_isempty +int +hash_isempty (hash_t * hash) +{ + return hash->nodecount == 0; +} + +static hnode_t * +hnode_alloc (void *context) +{ + return malloc (sizeof *hnode_alloc (NULL)); +} + +static void +hnode_free (hnode_t * node, void *context) +{ + free (node); +} + + +/* + * Create a hash table node dynamically and assign it the given data. + */ + +hnode_t * +hnode_create (void *data) +{ + hnode_t *node = malloc (sizeof *node); + if (node) { + node->data = data; + node->next = NULL; + } + return node; +} + +/* + * Initialize a client-supplied node + */ + +hnode_t * +hnode_init (hnode_t * hnode, void *data) +{ + hnode->data = data; + hnode->next = NULL; + return hnode; +} + +/* + * Destroy a dynamically allocated node. + */ + +void +hnode_destroy (hnode_t * hnode) +{ + free (hnode); +} + +#undef hnode_put +void +hnode_put (hnode_t * node, void *data) +{ + node->data = data; +} + +#undef hnode_get +void * +hnode_get (hnode_t * node) +{ + return node->data; +} + +#undef hnode_getkey +const void * +hnode_getkey (hnode_t * node) +{ + return node->key; +} + +#undef hash_count +hashcount_t +hash_count (hash_t * hash) +{ + return hash->nodecount; +} + +#undef hash_size +hashcount_t +hash_size (hash_t * hash) +{ + return hash->nchains; +} + +static hash_val_t +hash_fun_default (const void *key) +{ + static unsigned long randbox[] = { + 0x49848f1bU, 0xe6255dbaU, 0x36da5bdcU, 0x47bf94e9U, + 0x8cbcce22U, 0x559fc06aU, 0xd268f536U, 0xe10af79aU, + 0xc1af4d69U, 0x1d2917b5U, 0xec4c304dU, 0x9ee5016cU, + 0x69232f74U, 0xfead7bb3U, 0xe9089ab6U, 0xf012f6aeU, + }; + + const unsigned char *str = key; + hash_val_t acc = 0; + + while (*str) { + acc ^= randbox[(tolower (*str) + acc) & 0xf]; + acc = (acc << 1) | (acc >> 31); + acc &= 0xffffffffU; + acc ^= randbox[((tolower (*str++) >> 4) + acc) & 0xf]; + acc = (acc << 2) | (acc >> 30); + acc &= 0xffffffffU; + } + return acc; +} + +static int +hash_comp_default (const void *key1, const void *key2) +{ + return strcasecmp (key1, key2); +} + diff --git a/hash.h b/hash.h new file mode 100644 index 0000000..43cb77e --- /dev/null +++ b/hash.h @@ -0,0 +1,261 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** Portions borrowed from kazlib. Original Header follows: +*/ +/* + * Hash Table Data Type + * Copyright (C) 1997 Kaz Kylheku + * + * Free Software License: + * + * All rights are reserved by the author, with the following exceptions: + * Permission is granted to freely reproduce and distribute this software, + * possibly in exchange for a fee, provided that this copyright notice appears + * intact. Permission is also granted to adapt this software to produce + * derivative works, as long as the modified versions carry this copyright + * notice and additional notices stating that the work has been modified. + * This source code may be translated into executable form and incorporated + * into proprietary software; there is no requirement for such software to + * contain a copyright notice related to this source. + * + * $Id$ + * $Name: $ + */ + +#ifndef HASH_H +#define HASH_H + +#include +#ifdef KAZLIB_SIDEEFFECT_DEBUG +#include "sfx.h" +#endif + +/* + * Blurb for inclusion into C++ translation units + */ + +#ifdef __cplusplus +extern "C" { +#endif + + typedef unsigned long hashcount_t; +#define HASHCOUNT_T_MAX ULONG_MAX + + typedef unsigned long hash_val_t; +#define HASH_VAL_T_MAX ULONG_MAX + + extern int hash_val_t_bit; + +#ifndef HASH_VAL_T_BIT +#define HASH_VAL_T_BIT ((int) hash_val_t_bit) +#endif + +/* + * Hash chain node structure. + * Notes: + * 1. This preprocessing directive is for debugging purposes. The effect is + * that if the preprocessor symbol KAZLIB_OPAQUE_DEBUG is defined prior to the + * inclusion of this header, then the structure shall be declared as having + * the single member int __OPAQUE__. This way, any attempts by the + * client code to violate the principles of information hiding (by accessing + * the structure directly) can be diagnosed at translation time. However, + * note the resulting compiled unit is not suitable for linking. + * 2. This is a pointer to the next node in the chain. In the last node of a + * chain, this pointer is null. + * 3. The key is a pointer to some user supplied data that contains a unique + * identifier for each hash node in a given table. The interpretation of + * the data is up to the user. When creating or initializing a hash table, + * the user must supply a pointer to a function for comparing two keys, + * and a pointer to a function for hashing a key into a numeric value. + * 4. The value is a user-supplied pointer to void which may refer to + * any data object. It is not interpreted in any way by the hashing + * module. + * 5. The hashed key is stored in each node so that we don't have to rehash + * each key when the table must grow or shrink. + */ + + typedef struct hnode_t { +#if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) /* 1 */ + struct hnode_t *hash_next; /* 2 */ + const void *hash_key; /* 3 */ + void *hash_data; /* 4 */ + hash_val_t hash_hkey; /* 5 */ +#else + int hash_dummy; +#endif + } hnode_t; + +/* + * The comparison function pointer type. A comparison function takes two keys + * and produces a value of -1 if the left key is less than the right key, a + * value of 0 if the keys are equal, and a value of 1 if the left key is + * greater than the right key. + */ + + typedef int (*hash_comp_t) (const void *, const void *); + +/* + * The hashing function performs some computation on a key and produces an + * integral value of type hash_val_t based on that key. For best results, the + * function should have a good randomness properties in *all* significant bits + * over the set of keys that are being inserted into a given hash table. In + * particular, the most significant bits of hash_val_t are most significant to + * the hash module. Only as the hash table expands are less significant bits + * examined. Thus a function that has good distribution in its upper bits but + * not lower is preferrable to one that has poor distribution in the upper bits + * but not the lower ones. + */ + + typedef hash_val_t (*hash_fun_t) (const void *); + +/* + * allocator functions + */ + + typedef hnode_t *(*hnode_alloc_t) (void *); + typedef void (*hnode_free_t) (hnode_t *, void *); + +/* + * This is the hash table control structure. It keeps track of information + * about a hash table, as well as the hash table itself. + * Notes: + * 1. Pointer to the hash table proper. The table is an array of pointers to + * hash nodes (of type hnode_t). If the table is empty, every element of + * this table is a null pointer. A non-null entry points to the first + * element of a chain of nodes. + * 2. This member keeps track of the size of the hash table---that is, the + * number of chain pointers. + * 3. The count member maintains the number of elements that are presently + * in the hash table. + * 4. The maximum count is the greatest number of nodes that can populate this + * table. If the table contains this many nodes, no more can be inserted, + * and the hash_isfull() function returns true. + * 5. The high mark is a population threshold, measured as a number of nodes, + * which, if exceeded, will trigger a table expansion. Only dynamic hash + * tables are subject to this expansion. + * 6. The low mark is a minimum population threshold, measured as a number of + * nodes. If the table population drops below this value, a table shrinkage + * will occur. Only dynamic tables are subject to this reduction. No table + * will shrink beneath a certain absolute minimum number of nodes. + * 7. This is the a pointer to the hash table's comparison function. The + * function is set once at initialization or creation time. + * 8. Pointer to the table's hashing function, set once at creation or + * initialization time. + * 9. The current hash table mask. If the size of the hash table is 2^N, + * this value has its low N bits set to 1, and the others clear. It is used + * to select bits from the result of the hashing function to compute an + * index into the table. + * 10. A flag which indicates whether the table is to be dynamically resized. It + * is set to 1 in dynamically allocated tables, 0 in tables that are + * statically allocated. + */ + + typedef struct hash_t { +#if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) + struct hnode_t **hash_table; /* 1 */ + hashcount_t hash_nchains; /* 2 */ + hashcount_t hash_nodecount; /* 3 */ + hashcount_t hash_maxcount; /* 4 */ + hashcount_t hash_highmark; /* 5 */ + hashcount_t hash_lowmark; /* 6 */ + hash_comp_t hash_compare; /* 7 */ + hash_fun_t hash_function; /* 8 */ + hnode_alloc_t hash_allocnode; + hnode_free_t hash_freenode; + void *hash_context; + hash_val_t hash_mask; /* 9 */ + int hash_dynamic; /* 10 */ +#else + int hash_dummy; +#endif + } hash_t; + +/* + * Hash scanner structure, used for traversals of the data structure. + * Notes: + * 1. Pointer to the hash table that is being traversed. + * 2. Reference to the current chain in the table being traversed (the chain + * that contains the next node that shall be retrieved). + * 3. Pointer to the node that will be retrieved by the subsequent call to + * hash_scan_next(). + */ + + typedef struct hscan_t { +#if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) + hash_t *hash_table; /* 1 */ + hash_val_t hash_chain; /* 2 */ + hnode_t *hash_next; /* 3 */ +#else + int hash_dummy; +#endif + } hscan_t; + + extern hash_t *hash_create (hashcount_t, hash_comp_t, hash_fun_t); + extern void hash_set_allocator (hash_t *, hnode_alloc_t, hnode_free_t, void *); + extern void hash_destroy (hash_t *); + extern void hash_free_nodes (hash_t *); + extern void hash_free (hash_t *); + extern hash_t *hash_init (hash_t *, hashcount_t, hash_comp_t, hash_fun_t, hnode_t **, hashcount_t); + extern void hash_insert (hash_t *, hnode_t *, const void *); + extern hnode_t *hash_lookup (hash_t *, const void *); + extern hnode_t *hash_delete (hash_t *, hnode_t *); + extern int hash_alloc_insert (hash_t *, const void *, void *); + extern void hash_delete_free (hash_t *, hnode_t *); + + extern void hnode_put (hnode_t *, void *); + extern void *hnode_get (hnode_t *); + extern const void *hnode_getkey (hnode_t *); + extern hashcount_t hash_count (hash_t *); + extern hashcount_t hash_size (hash_t *); + + extern int hash_isfull (hash_t *); + extern int hash_isempty (hash_t *); + + extern void hash_scan_begin (hscan_t *, hash_t *); + extern hnode_t *hash_scan_next (hscan_t *); + extern hnode_t *hash_scan_delete (hash_t *, hnode_t *); + extern void hash_scan_delfree (hash_t *, hnode_t *); + + extern int hash_verify (hash_t *); + + extern hnode_t *hnode_create (void *); + extern hnode_t *hnode_init (hnode_t *, void *); + extern void hnode_destroy (hnode_t *); + +#if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) +#ifdef KAZLIB_SIDEEFFECT_DEBUG +#define hash_isfull(H) (SFX_CHECK(H)->hash_nodecount == (H)->hash_maxcount) +#else +#define hash_isfull(H) ((H)->hash_nodecount == (H)->hash_maxcount) +#endif +#define hash_isempty(H) ((H)->hash_nodecount == 0) +#define hash_count(H) ((H)->hash_nodecount) +#define hash_size(H) ((H)->hash_nchains) +#define hnode_get(N) ((N)->hash_data) +#define hnode_getkey(N) ((N)->hash_key) +#define hnode_put(N, V) ((N)->hash_data = (V)) +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..11870f1 --- /dev/null +++ b/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# 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. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + : +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f "$src" ] || [ -d "$src" ] + then + : + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + : + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + : + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + : + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# 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 $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/libevent/Makefile.am b/libevent/Makefile.am new file mode 100644 index 0000000..c299567 --- /dev/null +++ b/libevent/Makefile.am @@ -0,0 +1,33 @@ +AUTOMAKE_OPTIONS = foreign no-dependencies + +CFLAGS = -Wall @CFLAGS@ +SUBDIRS = . sample test + +EXTRA_DIST = acconfig.h err.c event.h evsignal.h event.3 kqueue.c \ + epoll_sub.c epoll.c select.c rtsig.c poll.c signal.c \ + sample/Makefile.am sample/Makefile.in sample/event-test.c \ + sample/signal-test.c sample/time-test.c \ + test/Makefile.am test/Makefile.in test/bench.c test/regress.c \ + test/test-eof.c test/test-weof.c test/test-time.c \ + test/test-init.c test/test.sh \ + compat/err.h compat/sys/queue.h compat/sys/tree.h compat/sys/_time.h \ + WIN32-Code WIN32-Code/config.h WIN32-Code/misc.c \ + WIN32-Code/win32.c WIN32-Code/misc.h \ + WIN32-Prj WIN32-Prj/event_test WIN32-Prj/event_test/event_test.dsp \ + WIN32-Prj/event_test/test.txt WIN32-Prj/libevent.dsp \ + WIN32-Prj/libevent.dsw WIN32-Prj/signal_test \ + WIN32-Prj/signal_test/signal_test.dsp WIN32-Prj/time_test \ + WIN32-Prj/time_test/time_test.dsp + +lib_LIBRARIES = libevent.a + +libevent_a_SOURCES = event.c buffer.c evbuffer.c +libevent_a_LIBADD = @LIBOBJS@ + +include_HEADERS = event.h + +INCLUDES = -Icompat + +man_MANS = event.3 + +DISTCLEANFILES = *~ diff --git a/libevent/Makefile.in b/libevent/Makefile.in new file mode 100644 index 0000000..d1d9af7 --- /dev/null +++ b/libevent/Makefile.in @@ -0,0 +1,523 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 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. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +CC = @CC@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ + +AUTOMAKE_OPTIONS = foreign no-dependencies + +CFLAGS = -Wall @CFLAGS@ +SUBDIRS = . sample test + +EXTRA_DIST = acconfig.h err.c event.h evsignal.h event.3 kqueue.c epoll_sub.c epoll.c select.c rtsig.c poll.c signal.c sample/Makefile.am sample/Makefile.in sample/event-test.c sample/signal-test.c sample/time-test.c test/Makefile.am test/Makefile.in test/bench.c test/regress.c test/test-eof.c test/test-weof.c test/test-time.c test/test-init.c test/test.sh compat/err.h compat/sys/queue.h compat/sys/tree.h compat/sys/_time.h WIN32-Code WIN32-Code/config.h WIN32-Code/misc.c WIN32-Code/win32.c WIN32-Code/misc.h WIN32-Prj WIN32-Prj/event_test WIN32-Prj/event_test/event_test.dsp WIN32-Prj/event_test/test.txt WIN32-Prj/libevent.dsp WIN32-Prj/libevent.dsw WIN32-Prj/signal_test WIN32-Prj/signal_test/signal_test.dsp WIN32-Prj/time_test WIN32-Prj/time_test/time_test.dsp + + +lib_LIBRARIES = libevent.a + +libevent_a_SOURCES = event.c buffer.c evbuffer.c +libevent_a_LIBADD = @LIBOBJS@ + +include_HEADERS = event.h + +INCLUDES = -Icompat + +man_MANS = event.3 + +DISTCLEANFILES = *~ +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(lib_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libevent_a_DEPENDENCIES = @LIBOBJS@ +libevent_a_OBJECTS = event.o buffer.o evbuffer.o +AR = ar +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +man3dir = $(mandir)/man3 +MANS = $(man_MANS) + +NROFF = nroff +HEADERS = $(include_HEADERS) + +DIST_COMMON = ./stamp-h.in Makefile.am Makefile.in acconfig.h \ +aclocal.m4 config.h.in configure configure.in err.c install-sh missing \ +mkinstalldirs + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(libevent_a_SOURCES) +OBJECTS = $(libevent_a_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +config.h: stamp-h + @if test ! -f $@; then \ + rm -f stamp-h; \ + $(MAKE) stamp-h; \ + else :; fi +stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=config.h \ + $(SHELL) ./config.status + @echo timestamp > stamp-h 2> /dev/null +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in + @if test ! -f $@; then \ + rm -f $(srcdir)/stamp-h.in; \ + $(MAKE) $(srcdir)/stamp-h.in; \ + else :; fi +$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h + cd $(top_srcdir) && $(AUTOHEADER) + @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f config.h + +maintainer-clean-hdr: + +mostlyclean-libLIBRARIES: + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +distclean-libLIBRARIES: + +maintainer-clean-libLIBRARIES: + +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \ + $(RANLIB) $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LIBRARIES)'; for p in $$list; do \ + rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +libevent.a: $(libevent_a_OBJECTS) $(libevent_a_DEPENDENCIES) + -rm -f libevent.a + $(AR) cru libevent.a $(libevent_a_OBJECTS) $(libevent_a_LIBADD) + $(RANLIB) libevent.a + +install-man3: + $(mkinstalldirs) $(DESTDIR)$(man3dir) + @list='$(man3_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst; \ + done + +uninstall-man3: + @list='$(man3_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.3*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man3dir)/$$inst"; \ + rm -f $(DESTDIR)$(man3dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-man3 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-man3 + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +# 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. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; 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; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" != "." || dot_seen=yes; \ + true; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(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 + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --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) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + $(mkinstalldirs) $(distdir)/WIN32-Code $(distdir)/WIN32-Prj \ + $(distdir)/WIN32-Prj/event_test \ + $(distdir)/WIN32-Prj/signal_test \ + $(distdir)/WIN32-Prj/time_test $(distdir)/compat \ + $(distdir)/compat/sys $(distdir)/sample $(distdir)/test + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +all-recursive-am: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +install-exec-am: install-libLIBRARIES +install-exec: install-exec-recursive + +install-data-am: install-man install-includeHEADERS +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-libLIBRARIES uninstall-man \ + uninstall-includeHEADERS +uninstall: uninstall-recursive +all-am: Makefile $(LIBRARIES) $(MANS) $(HEADERS) config.h +all-redirect: all-recursive-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(mandir)/man3 \ + $(DESTDIR)$(includedir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-hdr mostlyclean-libLIBRARIES \ + mostlyclean-compile mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-hdr clean-libLIBRARIES clean-compile clean-tags \ + clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-hdr distclean-libLIBRARIES distclean-compile \ + distclean-tags distclean-generic clean-am + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-hdr maintainer-clean-libLIBRARIES \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +mostlyclean-libLIBRARIES distclean-libLIBRARIES clean-libLIBRARIES \ +maintainer-clean-libLIBRARIES uninstall-libLIBRARIES \ +install-libLIBRARIES mostlyclean-compile distclean-compile \ +clean-compile maintainer-clean-compile install-man3 uninstall-man3 \ +install-man uninstall-man uninstall-includeHEADERS \ +install-includeHEADERS install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libevent/acconfig.h b/libevent/acconfig.h new file mode 100644 index 0000000..834e810 --- /dev/null +++ b/libevent/acconfig.h @@ -0,0 +1,64 @@ +/* Define if kqueue works correctly with pipes */ +#undef HAVE_WORKING_KQUEUE + +/* Define to `unsigned long long' if doesn't define. */ +#undef u_int64_t + +/* Define to `unsigned int' if doesn't define. */ +#undef u_int32_t + +/* Define to `unsigned short' if doesn't define. */ +#undef u_int16_t + +/* Define to `unsigned char' if doesn't define. */ +#undef u_int8_t + +/* Define if timeradd is defined in */ +#undef HAVE_TIMERADD +#ifndef HAVE_TIMERADD +#undef timerclear +#undef timerisset +#undef timercmp +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#define timercmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#define timeradd(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ + } \ + } while (0) +#define timersub(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) +#endif /* !HAVE_TIMERADD */ + +/* Define if TAILQ_FOREACH is defined in */ +#undef HAVE_TAILQFOREACH +#ifndef HAVE_TAILQFOREACH +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_END(head) NULL +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define TAILQ_FOREACH(var, head, field) \ + for((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_NEXT(var, field)) +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) +#endif /* TAILQ_FOREACH */ diff --git a/libevent/aclocal.m4 b/libevent/aclocal.m4 new file mode 100644 index 0000000..b245505 --- /dev/null +++ b/libevent/aclocal.m4 @@ -0,0 +1,190 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p6 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +# Do all the work for Automake. 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. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# Copyright 2002 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# 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. +AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.4"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.4-p6])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# 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 ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $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 + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN([AM_MISSING_PROG], +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. + +AC_DEFUN([AM_CONFIG_HEADER], +[AC_PREREQ([2.12]) +AC_CONFIG_HEADER([$1]) +dnl When config.status generates a header, we must update the stamp-h file. +dnl This file resides in the same directory as the config header +dnl that is generated. We must strip everything past the first ":", +dnl and everything past the last "/". +AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl +ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, +<>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, +<>; do + case " <<$>>CONFIG_HEADERS " in + *" <<$>>am_file "*<<)>> + echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx + ;; + esac + am_indx=`expr "<<$>>am_indx" + 1` +done<<>>dnl>>) +changequote([,]))]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +# Define a conditional. + +AC_DEFUN([AM_CONDITIONAL], +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + diff --git a/libevent/buffer.c b/libevent/buffer.c new file mode 100644 index 0000000..393188b --- /dev/null +++ b/libevent/buffer.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2002, 2003 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#include +#include +#include +#include +#include +#ifdef HAVE_STDARG_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "event.h" + +struct evbuffer * +evbuffer_new(void) +{ + struct evbuffer *buffer; + + buffer = calloc(1, sizeof(struct evbuffer)); + + return (buffer); +} + +void +evbuffer_free(struct evbuffer *buffer) +{ + if (buffer->buffer != NULL) + free(buffer->buffer); + free(buffer); +} + +/* + * This is a destructive add. The data from one buffer moves into + * the other buffer. + */ + +int +evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf) +{ + int res; + res = evbuffer_add(outbuf, inbuf->buffer, inbuf->off); + if (res == 0) + evbuffer_drain(inbuf, inbuf->off); + + return (res); +} + +int +evbuffer_add_printf(struct evbuffer *buf, char *fmt, ...) +{ + int res = -1; + char *msg; + va_list ap; + + va_start(ap, fmt); + + if (vasprintf(&msg, fmt, ap) == -1) + goto end; + + res = strlen(msg); + if (evbuffer_add(buf, msg, res) == -1) + res = -1; + free(msg); + + end: + va_end(ap); + + return (res); +} + +int +evbuffer_add(struct evbuffer *buf, u_char *data, size_t datlen) +{ + size_t need = buf->off + datlen; + size_t oldoff = buf->off; + + if (buf->totallen < need) { + void *newbuf; + int length = buf->totallen; + + if (length < 256) + length = 256; + while (length < need) + length <<= 1; + + if ((newbuf = realloc(buf->buffer, length)) == NULL) + return (-1); + + buf->buffer = newbuf; + buf->totallen = length; + } + + memcpy(buf->buffer + buf->off, data, datlen); + buf->off += datlen; + + if (datlen && buf->cb != NULL) + (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); + + return (0); +} + +void +evbuffer_drain(struct evbuffer *buf, size_t len) +{ + size_t oldoff = buf->off; + + if (len >= buf->off) { + buf->off = 0; + goto done; + } + + memmove(buf->buffer, buf->buffer + len, buf->off - len); + buf->off -= len; + + done: + /* Tell someone about changes in this buffer */ + if (buf->off != oldoff && buf->cb != NULL) + (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); + +} + +int +evbuffer_read(struct evbuffer *buffer, int fd, int howmuch) +{ + u_char inbuf[4096]; + int n; + + if (howmuch < 0 || howmuch > sizeof(inbuf)) + howmuch = sizeof(inbuf); + + n = read(fd, inbuf, howmuch); + if (n == -1) + return (-1); + if (n == 0) + return (0); + + evbuffer_add(buffer, inbuf, n); + + return (n); +} + +int +evbuffer_write(struct evbuffer *buffer, int fd) +{ + int n; + + n = write(fd, buffer->buffer, buffer->off); + if (n == -1) + return (-1); + if (n == 0) + return (0); + + evbuffer_drain(buffer, n); + + return (n); +} + +u_char * +evbuffer_find(struct evbuffer *buffer, u_char *what, size_t len) +{ + size_t remain = buffer->off; + u_char *search = buffer->buffer; + u_char *p; + + while ((p = memchr(search, *what, remain)) != NULL && remain >= len) { + if (memcmp(p, what, len) == 0) + return (p); + + search = p + 1; + remain = buffer->off - (size_t)(search - buffer->buffer); + } + + return (NULL); +} + +void evbuffer_setcb(struct evbuffer *buffer, + void (*cb)(struct evbuffer *, size_t, size_t, void *), + void *cbarg) +{ + buffer->cb = cb; + buffer->cbarg = cbarg; +} diff --git a/libevent/compat/err.h b/libevent/compat/err.h new file mode 100644 index 0000000..4b7317b --- /dev/null +++ b/libevent/compat/err.h @@ -0,0 +1,46 @@ +/* + * err.h + * + * Adapted from OpenBSD libc *err* *warn* code. + * + * Copyright (c) 2000 Dug Song + * + * Copyright (c) 1993 + * The Regents of the University of California. 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. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)err.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _ERR_H_ +#define _ERR_H_ + +void err(int eval, const char *fmt, ...); +void warn(const char *fmt, ...); +void errx(int eval, const char *fmt, ...); +void warnx(const char *fmt, ...); + +#endif /* !_ERR_H_ */ diff --git a/libevent/compat/sys/_time.h b/libevent/compat/sys/_time.h new file mode 100644 index 0000000..8cabb0d --- /dev/null +++ b/libevent/compat/sys/_time.h @@ -0,0 +1,163 @@ +/* $OpenBSD: time.h,v 1.11 2000/10/10 13:36:48 itojun Exp $ */ +/* $NetBSD: time.h,v 1.18 1996/04/23 10:29:33 mycroft Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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. + * + * @(#)time.h 8.2 (Berkeley) 7/10/94 + */ + +#ifndef _SYS_TIME_H_ +#define _SYS_TIME_H_ + +#include + +/* + * Structure returned by gettimeofday(2) system call, + * and used in other calls. + */ +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; + +/* + * Structure defined by POSIX.1b to be like a timeval. + */ +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +}; + +#define TIMEVAL_TO_TIMESPEC(tv, ts) { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ +} +#define TIMESPEC_TO_TIMEVAL(tv, ts) { \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ +} + +struct timezone { + int tz_minuteswest; /* minutes west of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; +#define DST_NONE 0 /* not on dst */ +#define DST_USA 1 /* USA style dst */ +#define DST_AUST 2 /* Australian style dst */ +#define DST_WET 3 /* Western European dst */ +#define DST_MET 4 /* Middle European dst */ +#define DST_EET 5 /* Eastern European dst */ +#define DST_CAN 6 /* Canada */ + +/* Operations on timevals. */ +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#define timercmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#define timeradd(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ + } \ + } while (0) +#define timersub(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) + +/* Operations on timespecs. */ +#define timespecclear(tsp) (tsp)->tv_sec = (tsp)->tv_nsec = 0 +#define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec) +#define timespeccmp(tsp, usp, cmp) \ + (((tsp)->tv_sec == (usp)->tv_sec) ? \ + ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ + ((tsp)->tv_sec cmp (usp)->tv_sec)) +#define timespecadd(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \ + if ((vsp)->tv_nsec >= 1000000000L) { \ + (vsp)->tv_sec++; \ + (vsp)->tv_nsec -= 1000000000L; \ + } \ + } while (0) +#define timespecsub(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \ + if ((vsp)->tv_nsec < 0) { \ + (vsp)->tv_sec--; \ + (vsp)->tv_nsec += 1000000000L; \ + } \ + } while (0) + +/* + * Names of the interval timers, and structure + * defining a timer setting. + */ +#define ITIMER_REAL 0 +#define ITIMER_VIRTUAL 1 +#define ITIMER_PROF 2 + +struct itimerval { + struct timeval it_interval; /* timer interval */ + struct timeval it_value; /* current value */ +}; + +/* + * Getkerninfo clock information structure + */ +struct clockinfo { + int hz; /* clock frequency */ + int tick; /* micro-seconds per hz tick */ + int tickadj; /* clock skew rate for adjtime() */ + int stathz; /* statistics clock frequency */ + int profhz; /* profiling clock frequency */ +}; + +#define CLOCK_REALTIME 0 +#define CLOCK_VIRTUAL 1 +#define CLOCK_PROF 2 + +#define TIMER_RELTIME 0x0 /* relative timer */ +#define TIMER_ABSTIME 0x1 /* absolute timer */ + +/* --- stuff got cut here - niels --- */ + +#endif /* !_SYS_TIME_H_ */ diff --git a/libevent/compat/sys/queue.h b/libevent/compat/sys/queue.h new file mode 100644 index 0000000..c0956dd --- /dev/null +++ b/libevent/compat/sys/queue.h @@ -0,0 +1,488 @@ +/* $OpenBSD: queue.h,v 1.16 2000/09/07 19:47:59 art Exp $ */ +/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +/* + * This file defines five types of data structures: singly-linked lists, + * lists, simple queues, tail queues, and circular queues. + * + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#ifndef WIN32 +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} +#endif + +/* + * Singly-linked List access methods. + */ +#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_END(head) NULL +#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_FOREACH(var, head, field) \ + for((var) = SLIST_FIRST(head); \ + (var) != SLIST_END(head); \ + (var) = SLIST_NEXT(var, field)) + +/* + * Singly-linked List functions. + */ +#define SLIST_INIT(head) { \ + SLIST_FIRST(head) = SLIST_END(head); \ +} + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (0) + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List access methods + */ +#define LIST_FIRST(head) ((head)->lh_first) +#define LIST_END(head) NULL +#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_FOREACH(var, head, field) \ + for((var) = LIST_FIRST(head); \ + (var)!= LIST_END(head); \ + (var) = LIST_NEXT(var, field)) + +/* + * List functions. + */ +#define LIST_INIT(head) do { \ + LIST_FIRST(head) = LIST_END(head); \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} while (0) + +#define LIST_REMOVE(elm, field) do { \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ +} while (0) + +#define LIST_REPLACE(elm, elm2, field) do { \ + if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ + (elm2)->field.le_next->field.le_prev = \ + &(elm2)->field.le_next; \ + (elm2)->field.le_prev = (elm)->field.le_prev; \ + *(elm2)->field.le_prev = (elm2); \ +} while (0) + +/* + * Simple queue definitions. + */ +#define SIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define SIMPLEQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).sqh_first } + +#define SIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +/* + * Simple queue access methods. + */ +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_END(head) NULL +#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + +#define SIMPLEQ_FOREACH(var, head, field) \ + for((var) = SIMPLEQ_FIRST(head); \ + (var) != SIMPLEQ_END(head); \ + (var) = SIMPLEQ_NEXT(var, field)) + +/* + * Simple queue functions. + */ +#define SIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ +} while (0) + +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (0) + +#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ +} while (0) + +#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \ + if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * tail queue access methods + */ +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_END(head) NULL +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +/* XXX */ +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) +#define TAILQ_EMPTY(head) \ + (TAILQ_FIRST(head) == TAILQ_END(head)) + +#define TAILQ_FOREACH(var, head, field) \ + for((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_NEXT(var, field)) + +#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \ + for((var) = TAILQ_LAST(head, headname); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_PREV(var, headname, field)) + +/* + * Tail queue functions. + */ +#define TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ + (elm2)->field.tqe_next->field.tqe_prev = \ + &(elm2)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm2)->field.tqe_next; \ + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ + *(elm2)->field.tqe_prev = (elm2); \ +} while (0) + +/* + * Circular queue definitions. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_HEAD_INITIALIZER(head) \ + { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue access methods + */ +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) +#define CIRCLEQ_LAST(head) ((head)->cqh_last) +#define CIRCLEQ_END(head) ((void *)(head)) +#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) +#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) +#define CIRCLEQ_EMPTY(head) \ + (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for((var) = CIRCLEQ_FIRST(head); \ + (var) != CIRCLEQ_END(head); \ + (var) = CIRCLEQ_NEXT(var, field)) + +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ + for((var) = CIRCLEQ_LAST(head); \ + (var) != CIRCLEQ_END(head); \ + (var) = CIRCLEQ_PREV(var, field)) + +/* + * Circular queue functions. + */ +#define CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = CIRCLEQ_END(head); \ + (head)->cqh_last = CIRCLEQ_END(head); \ +} while (0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = CIRCLEQ_END(head); \ + if ((head)->cqh_last == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.cqe_next = CIRCLEQ_END(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (0) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ +} while (0) + +#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ + CIRCLEQ_END(head)) \ + (head).cqh_last = (elm2); \ + else \ + (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ + if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ + CIRCLEQ_END(head)) \ + (head).cqh_first = (elm2); \ + else \ + (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ +} while (0) + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/libevent/compat/sys/tree.h b/libevent/compat/sys/tree.h new file mode 100644 index 0000000..6a3381c --- /dev/null +++ b/libevent/compat/sys/tree.h @@ -0,0 +1,677 @@ +/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ +/* + * Copyright 2002 Niels Provos + * 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. + */ + +#ifndef _SYS_TREE_H_ +#define _SYS_TREE_H_ + +/* + * This file defines data structures for different types of trees: + * splay trees and red-black trees. + * + * A splay tree is a self-organizing data structure. Every operation + * on the tree causes a splay to happen. The splay moves the requested + * node to the root of the tree and partly rebalances it. + * + * This has the benefit that request locality causes faster lookups as + * the requested nodes move to the top of the tree. On the other hand, + * every lookup causes memory writes. + * + * The Balance Theorem bounds the total access time for m operations + * and n inserts on an initially empty tree as O((m + n)lg n). The + * amortized cost for a sequence of m accesses to a splay tree is O(lg n); + * + * A red-black tree is a binary search tree with the node color as an + * extra attribute. It fulfills a set of conditions: + * - every search path from the root to a leaf consists of the + * same number of black nodes, + * - each red node (except for the root) has a black parent, + * - each leaf node is black. + * + * Every operation on a red-black tree is bounded as O(lg n). + * The maximum height of a red-black tree is 2lg (n+1). + */ + +#define SPLAY_HEAD(name, type) \ +struct name { \ + struct type *sph_root; /* root of the tree */ \ +} + +#define SPLAY_INITIALIZER(root) \ + { NULL } + +#define SPLAY_INIT(root) do { \ + (root)->sph_root = NULL; \ +} while (0) + +#define SPLAY_ENTRY(type) \ +struct { \ + struct type *spe_left; /* left element */ \ + struct type *spe_right; /* right element */ \ +} + +#define SPLAY_LEFT(elm, field) (elm)->field.spe_left +#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right +#define SPLAY_ROOT(head) (head)->sph_root +#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) + +/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ +#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (0) + +#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (0) + +#define SPLAY_LINKLEFT(head, tmp, field) do { \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ +} while (0) + +#define SPLAY_LINKRIGHT(head, tmp, field) do { \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ +} while (0) + +#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ + SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ + SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ +} while (0) + +/* Generates prototypes and inline functions */ + +#define SPLAY_PROTOTYPE(name, type, field, cmp) \ +void name##_SPLAY(struct name *, struct type *); \ +void name##_SPLAY_MINMAX(struct name *, int); \ +struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ +struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ + \ +/* Finds the node with the same key as elm */ \ +static __inline struct type * \ +name##_SPLAY_FIND(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) \ + return(NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) \ + return (head->sph_root); \ + return (NULL); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_NEXT(struct name *head, struct type *elm) \ +{ \ + name##_SPLAY(head, elm); \ + if (SPLAY_RIGHT(elm, field) != NULL) { \ + elm = SPLAY_RIGHT(elm, field); \ + while (SPLAY_LEFT(elm, field) != NULL) { \ + elm = SPLAY_LEFT(elm, field); \ + } \ + } else \ + elm = NULL; \ + return (elm); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_MIN_MAX(struct name *head, int val) \ +{ \ + name##_SPLAY_MINMAX(head, val); \ + return (SPLAY_ROOT(head)); \ +} + +/* Main splay operation. + * Moves node close to the key of elm to top + */ +#define SPLAY_GENERATE(name, type, field, cmp) \ +struct type * \ +name##_SPLAY_INSERT(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) { \ + SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ + } else { \ + int __comp; \ + name##_SPLAY(head, elm); \ + __comp = (cmp)(elm, (head)->sph_root); \ + if(__comp < 0) { \ + SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ + SPLAY_RIGHT(elm, field) = (head)->sph_root; \ + SPLAY_LEFT((head)->sph_root, field) = NULL; \ + } else if (__comp > 0) { \ + SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT(elm, field) = (head)->sph_root; \ + SPLAY_RIGHT((head)->sph_root, field) = NULL; \ + } else \ + return ((head)->sph_root); \ + } \ + (head)->sph_root = (elm); \ + return (NULL); \ +} \ + \ +struct type * \ +name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *__tmp; \ + if (SPLAY_EMPTY(head)) \ + return (NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) { \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ + } else { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ + name##_SPLAY(head, elm); \ + SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ + } \ + return (elm); \ + } \ + return (NULL); \ +} \ + \ +void \ +name##_SPLAY(struct name *head, struct type *elm) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ + int __comp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while ((__comp = (cmp)(elm, (head)->sph_root))) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) > 0){ \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} \ + \ +/* Splay with either the minimum or the maximum element \ + * Used to find minimum or maximum element in tree. \ + */ \ +void name##_SPLAY_MINMAX(struct name *head, int __comp) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while (1) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp > 0) { \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} + +#define SPLAY_NEGINF -1 +#define SPLAY_INF 1 + +#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) +#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) +#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) +#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) +#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) +#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) + +#define SPLAY_FOREACH(x, name, head) \ + for ((x) = SPLAY_MIN(name, head); \ + (x) != NULL; \ + (x) = SPLAY_NEXT(name, head, x)) + +/* Macros that define a red-back tree */ +#define RB_HEAD(name, type) \ +struct name { \ + struct type *rbh_root; /* root of the tree */ \ +} + +#define RB_INITIALIZER(root) \ + { NULL } + +#define RB_INIT(root) do { \ + (root)->rbh_root = NULL; \ +} while (0) + +#define RB_BLACK 0 +#define RB_RED 1 +#define RB_ENTRY(type) \ +struct { \ + struct type *rbe_left; /* left element */ \ + struct type *rbe_right; /* right element */ \ + struct type *rbe_parent; /* parent element */ \ + int rbe_color; /* node color */ \ +} + +#define RB_LEFT(elm, field) (elm)->field.rbe_left +#define RB_RIGHT(elm, field) (elm)->field.rbe_right +#define RB_PARENT(elm, field) (elm)->field.rbe_parent +#define RB_COLOR(elm, field) (elm)->field.rbe_color +#define RB_ROOT(head) (head)->rbh_root +#define RB_EMPTY(head) (RB_ROOT(head) == NULL) + +#define RB_SET(elm, parent, field) do { \ + RB_PARENT(elm, field) = parent; \ + RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ + RB_COLOR(elm, field) = RB_RED; \ +} while (0) + +#define RB_SET_BLACKRED(black, red, field) do { \ + RB_COLOR(black, field) = RB_BLACK; \ + RB_COLOR(red, field) = RB_RED; \ +} while (0) + +#ifndef RB_AUGMENT +#define RB_AUGMENT(x) +#endif + +#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ + (tmp) = RB_RIGHT(elm, field); \ + if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \ + RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_LEFT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (0) + +#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ + (tmp) = RB_LEFT(elm, field); \ + if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \ + RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_RIGHT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (0) + +/* Generates prototypes and inline functions */ +#define RB_PROTOTYPE(name, type, field, cmp) \ +void name##_RB_INSERT_COLOR(struct name *, struct type *); \ +void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ +struct type *name##_RB_REMOVE(struct name *, struct type *); \ +struct type *name##_RB_INSERT(struct name *, struct type *); \ +struct type *name##_RB_FIND(struct name *, struct type *); \ +struct type *name##_RB_NEXT(struct type *); \ +struct type *name##_RB_MINMAX(struct name *, int); \ + \ + +/* Main rb operation. + * Moves node close to the key of elm to top + */ +#define RB_GENERATE(name, type, field, cmp) \ +void \ +name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ +{ \ + struct type *parent, *gparent, *tmp; \ + while ((parent = RB_PARENT(elm, field)) && \ + RB_COLOR(parent, field) == RB_RED) { \ + gparent = RB_PARENT(parent, field); \ + if (parent == RB_LEFT(gparent, field)) { \ + tmp = RB_RIGHT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field);\ + elm = gparent; \ + continue; \ + } \ + if (RB_RIGHT(parent, field) == elm) { \ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_RIGHT(head, gparent, tmp, field); \ + } else { \ + tmp = RB_LEFT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field);\ + elm = gparent; \ + continue; \ + } \ + if (RB_LEFT(parent, field) == elm) { \ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_LEFT(head, gparent, tmp, field); \ + } \ + } \ + RB_COLOR(head->rbh_root, field) = RB_BLACK; \ +} \ + \ +void \ +name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ +{ \ + struct type *tmp; \ + while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ + elm != RB_ROOT(head)) { \ + if (RB_LEFT(parent, field) == elm) { \ + tmp = RB_RIGHT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + tmp = RB_RIGHT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ + struct type *oleft; \ + if ((oleft = RB_LEFT(tmp, field)))\ + RB_COLOR(oleft, field) = RB_BLACK;\ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_RIGHT(head, tmp, oleft, field);\ + tmp = RB_RIGHT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_RIGHT(tmp, field)) \ + RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + elm = RB_ROOT(head); \ + break; \ + } \ + } else { \ + tmp = RB_LEFT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + tmp = RB_LEFT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ + struct type *oright; \ + if ((oright = RB_RIGHT(tmp, field)))\ + RB_COLOR(oright, field) = RB_BLACK;\ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_LEFT(head, tmp, oright, field);\ + tmp = RB_LEFT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_LEFT(tmp, field)) \ + RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + elm = RB_ROOT(head); \ + break; \ + } \ + } \ + } \ + if (elm) \ + RB_COLOR(elm, field) = RB_BLACK; \ +} \ + \ +struct type * \ +name##_RB_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *child, *parent, *old = elm; \ + int color; \ + if (RB_LEFT(elm, field) == NULL) \ + child = RB_RIGHT(elm, field); \ + else if (RB_RIGHT(elm, field) == NULL) \ + child = RB_LEFT(elm, field); \ + else { \ + struct type *left; \ + elm = RB_RIGHT(elm, field); \ + while ((left = RB_LEFT(elm, field))) \ + elm = left; \ + child = RB_RIGHT(elm, field); \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ + if (RB_PARENT(elm, field) == old) \ + parent = elm; \ + (elm)->field = (old)->field; \ + if (RB_PARENT(old, field)) { \ + if (RB_LEFT(RB_PARENT(old, field), field) == old)\ + RB_LEFT(RB_PARENT(old, field), field) = elm;\ + else \ + RB_RIGHT(RB_PARENT(old, field), field) = elm;\ + RB_AUGMENT(RB_PARENT(old, field)); \ + } else \ + RB_ROOT(head) = elm; \ + RB_PARENT(RB_LEFT(old, field), field) = elm; \ + if (RB_RIGHT(old, field)) \ + RB_PARENT(RB_RIGHT(old, field), field) = elm; \ + if (parent) { \ + left = parent; \ + do { \ + RB_AUGMENT(left); \ + } while ((left = RB_PARENT(left, field))); \ + } \ + goto color; \ + } \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ +color: \ + if (color == RB_BLACK) \ + name##_RB_REMOVE_COLOR(head, parent, child); \ + return (old); \ +} \ + \ +/* Inserts a node into the RB tree */ \ +struct type * \ +name##_RB_INSERT(struct name *head, struct type *elm) \ +{ \ + struct type *tmp; \ + struct type *parent = NULL; \ + int comp = 0; \ + tmp = RB_ROOT(head); \ + while (tmp) { \ + parent = tmp; \ + comp = (cmp)(elm, parent); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + RB_SET(elm, parent, field); \ + if (parent != NULL) { \ + if (comp < 0) \ + RB_LEFT(parent, field) = elm; \ + else \ + RB_RIGHT(parent, field) = elm; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = elm; \ + name##_RB_INSERT_COLOR(head, elm); \ + return (NULL); \ +} \ + \ +/* Finds the node with the same key as elm */ \ +struct type * \ +name##_RB_FIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (NULL); \ +} \ + \ +struct type * \ +name##_RB_NEXT(struct type *elm) \ +{ \ + if (RB_RIGHT(elm, field)) { \ + elm = RB_RIGHT(elm, field); \ + while (RB_LEFT(elm, field)) \ + elm = RB_LEFT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +struct type * \ +name##_RB_MINMAX(struct name *head, int val) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *parent = NULL; \ + while (tmp) { \ + parent = tmp; \ + if (val < 0) \ + tmp = RB_LEFT(tmp, field); \ + else \ + tmp = RB_RIGHT(tmp, field); \ + } \ + return (parent); \ +} + +#define RB_NEGINF -1 +#define RB_INF 1 + +#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) +#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) +#define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NEXT(name, x, y) name##_RB_NEXT(y) +#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) +#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) + +#define RB_FOREACH(x, name, head) \ + for ((x) = RB_MIN(name, head); \ + (x) != NULL; \ + (x) = name##_RB_NEXT(x)) + +#endif /* _SYS_TREE_H_ */ diff --git a/libevent/config.h.in b/libevent/config.h.in new file mode 100644 index 0000000..2c2b372 --- /dev/null +++ b/libevent/config.h.in @@ -0,0 +1,191 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ +/* Define if kqueue works correctly with pipes */ +#undef HAVE_WORKING_KQUEUE + +/* Define to `unsigned long long' if doesn't define. */ +#undef u_int64_t + +/* Define to `unsigned int' if doesn't define. */ +#undef u_int32_t + +/* Define to `unsigned short' if doesn't define. */ +#undef u_int16_t + +/* Define to `unsigned char' if doesn't define. */ +#undef u_int8_t + +/* Define if timeradd is defined in */ +#undef HAVE_TIMERADD +#ifndef HAVE_TIMERADD +#undef timerclear +#undef timerisset +#undef timercmp +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#define timercmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#define timeradd(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ + } \ + } while (0) +#define timersub(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) +#endif /* !HAVE_TIMERADD */ + +/* Define if TAILQ_FOREACH is defined in */ +#undef HAVE_TAILQFOREACH +#ifndef HAVE_TAILQFOREACH +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_END(head) NULL +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define TAILQ_FOREACH(var, head, field) \ + for((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_NEXT(var, field)) +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) +#endif /* TAILQ_FOREACH */ + +/* Define if your system supports the epoll system calls */ +#undef HAVE_EPOLL + +/* Define if you have the `epoll_ctl' function. */ +#undef HAVE_EPOLL_CTL + +/* Define if you have the `err' function. */ +#undef HAVE_ERR + +/* Define if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define if you have the `kqueue' function. */ +#undef HAVE_KQUEUE + +/* Define if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have the `poll' function. */ +#undef HAVE_POLL + +/* Define if you have the header file. */ +#undef HAVE_POLL_H + +/* Define if your system supports POSIX realtime signals */ +#undef HAVE_RTSIG + +/* Define if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define if you have the `sigtimedwait' function. */ +#undef HAVE_SIGTIMEDWAIT + +/* Define if you have the header file. */ +#undef HAVE_STDARG_H + +/* Define if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_EPOLL_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_EVENT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_QUEUE_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define if TAILQ_FOREACH is defined in */ +#undef HAVE_TAILQFOREACH + +/* Define if timeradd is defined in */ +#undef HAVE_TIMERADD + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the `vasprintf' function. */ +#undef HAVE_VASPRINTF + +/* Define if kqueue works correctly with pipes */ +#undef HAVE_WORKING_KQUEUE + +/* Define if realtime signals work on pipes */ +#undef HAVE_WORKING_RTSIG + +/* Name of package */ +#undef PACKAGE + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned' if does not define. */ +#undef size_t + +/* Define to unsigned int if you dont have it */ +#undef socklen_t + +/* Define to `unsigned short' if does not define. */ +#undef u_int16_t + +/* Define to `unsigned int' if does not define. */ +#undef u_int32_t + +/* Define to `unsigned long long' if does not define. */ +#undef u_int64_t + +/* Define to `unsigned char' if does not define. */ +#undef u_int8_t diff --git a/libevent/configure b/libevent/configure new file mode 100755 index 0000000..72c67ca --- /dev/null +++ b/libevent/configure @@ -0,0 +1,4731 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by Autoconf 2.52. +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# 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 + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Name of the executable. +as_me=`echo "$0" |sed 's,.*[\\/],,'` + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +# NLS nuisances. +$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; } +$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; } +$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; } +$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; } +$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; } +$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; } +$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; } +$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; } + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; } + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +cross_compiling=no +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +ac_unique_file="event.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# 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. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_prev= +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 + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -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 | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$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 ;; + + -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 ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + 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) + 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 ;; + + -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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=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 ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + 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'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: should be removed in autoconf 3.0. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + 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 + +# 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 its parent. + ac_prog=$0 + ac_confdir=`echo "$ac_prog" | sed 's%[\\/][^\\/][^\\/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + 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 + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# 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 < if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +EOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_subdir in : $ac_subdirs_all; do test "x$ac_subdir" = x: && continue + cd $ac_subdir + # A "../" for each directory in /$ac_subdir. + ac_dots=`echo $ac_subdir | + sed 's,^\./,,;s,[^/]$,&/,;s,[^/]*/,../,g'` + + case $srcdir in + .) # No --srcdir option. We are building in place. + ac_sub_srcdir=$srcdir ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_sub_srcdir=$srcdir/$ac_subdir ;; + *) # Relative path. + ac_sub_srcdir=$ac_dots$srcdir/$ac_subdir ;; + esac + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_sub_srcdir/configure.gnu; then + echo + $SHELL $ac_sub_srcdir/configure.gnu --help=recursive + elif test -f $ac_sub_srcdir/configure; then + echo + $SHELL $ac_sub_srcdir/configure --help=recursive + elif test -f $ac_sub_srcdir/configure.ac || + test -f $ac_sub_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_subdir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\EOF + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +EOF + exit 0 +fi +exec 5>config.log +cat >&5 </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` +hostinfo = `(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` + +PATH = $PATH + +_ASUNAME +} >&5 + +cat >&5 <\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + ac_sep=" " ;; + *) ac_configure_args="$ac_configure_args$ac_sep$ac_arg" + ac_sep=" " ;; + esac + # Get rid of the leading space. +done + +# 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. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + echo >&5 + echo "## ----------------- ##" >&5 + echo "## Cache variables. ##" >&5 + echo "## ----------------- ##" >&5 + echo >&5 + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} >&5 + sed "/^$/d" confdefs.h >conftest.log + if test -s conftest.log; then + echo >&5 + echo "## ------------ ##" >&5 + echo "## confdefs.h. ##" >&5 + echo "## ------------ ##" >&5 + echo >&5 + cat conftest.log >&5 + fi + (echo; echo) >&5 + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" >&5 + echo "$as_me: exit $exit_status" >&5 + rm -rf conftest* confdefs* core core.* *.core conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:871: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + cat "$ac_site_file" >&5 + . "$ac_site_file" + 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. + if test -f "$cache_file"; then + { echo "$as_me:882: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:890: creating cache $cache_file" >&5 +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 `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; 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,) + { echo "$as_me:906: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:910: error: \`$ac_var' was not set in the previous run" >&5 +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 + { echo "$as_me:916: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:918: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:920: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. It doesn't matter if + # we pass some twice (in addition to the command line arguments). + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + *) ac_configure_args="$ac_configure_args $ac_var=$ac_new_val" + ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:939: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:941: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +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 + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac +echo "#! $SHELL" >conftest.sh +echo "exit 0" >>conftest.sh +chmod +x conftest.sh +if { (echo "$as_me:961: PATH=\".;.\"; conftest.sh") >&5 + (PATH=".;."; conftest.sh) 2>&5 + ac_status=$? + echo "$as_me:964: \$? = $ac_status" >&5 + (exit $ac_status); }; then + ac_path_separator=';' +else + ac_path_separator=: +fi +PATH_SEPARATOR="$ac_path_separator" +rm -f conftest.sh + +am__api_version="1.4" +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; 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 + { { echo "$as_me:991: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# 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" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:1011: checking for a BSD compatible install" >&5 +echo $ECHO_N "checking for a BSD compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_IFS=$IFS; IFS=$ac_path_separator + for ac_dir in $PATH; do + IFS=$ac_save_IFS + # Account for people who put trailing slashes in PATH elements. + case $ac_dir/ in + / | ./ | .// | /cC/* \ + | /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* \ + | /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 + if $as_executable_p "$ac_dir/$ac_prog"; then + if test $ac_prog = install && + grep dspmsg "$ac_dir/$ac_prog" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$ac_dir/$ac_prog" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + +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. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:1060: result: $INSTALL" >&5 +echo "${ECHO_T}$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' + +echo "$as_me:1071: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftestfile +# 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 ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $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". + { { echo "$as_me:1094: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { { echo "$as_me:1107: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f conftest* +echo "$as_me:1114: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +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 $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + +echo "$as_me:1129: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:1149: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:1153: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +PACKAGE=libevent + +VERSION=0.8 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { { echo "$as_me:1163: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +cat >>confdefs.h <>confdefs.h <&5 +echo $ECHO_N "checking for working aclocal-${am__api_version}... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal-${am__api_version} + echo "$as_me:1184: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + ACLOCAL="$missing_dir/missing aclocal-${am__api_version}" + echo "$as_me:1188: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:1192: checking for working autoconf" >&5 +echo $ECHO_N "checking for working autoconf... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$as_me:1199: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$as_me:1203: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:1207: checking for working automake-${am__api_version}" >&5 +echo $ECHO_N "checking for working automake-${am__api_version}... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake-${am__api_version} + echo "$as_me:1214: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + AUTOMAKE="$missing_dir/missing automake-${am__api_version}" + echo "$as_me:1218: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:1222: checking for working autoheader" >&5 +echo $ECHO_N "checking for working autoheader... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$as_me:1229: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$as_me:1233: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +echo "$as_me:1237: checking for working makeinfo" >&5 +echo $ECHO_N "checking for working makeinfo... $ECHO_C" >&6 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$as_me:1244: result: found" >&5 +echo "${ECHO_T}found" >&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$as_me:1248: result: missing" >&5 +echo "${ECHO_T}missing" >&6 +fi + +ac_config_headers="$ac_config_headers config.h" + +ac_config_commands="$ac_config_commands default-1" + +echo "$as_me:1256: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi; + echo "$as_me:1265: result: $USE_MAINTAINER_MODE" >&5 +echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6 + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + +if test "$prefix" = "NONE"; then + prefix="/usr/local" +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 +echo "$as_me:1289: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_CC="${ac_tool_prefix}gcc" +echo "$as_me:1304: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1312: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1315: result: no" >&5 +echo "${ECHO_T}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 +echo "$as_me:1324: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_CC="gcc" +echo "$as_me:1339: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:1347: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:1350: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +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 +echo "$as_me:1363: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_CC="${ac_tool_prefix}cc" +echo "$as_me:1378: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1386: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1389: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:1398: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_CC="cc" +echo "$as_me:1413: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:1421: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:1424: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +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 +echo "$as_me:1437: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue +fi +ac_cv_prog_CC="cc" +echo "$as_me:1457: found $ac_dir/$ac_word" >&5 +break +done + +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 + set dummy "$ac_dir/$ac_word" ${1+"$@"} + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1479: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1482: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + 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 +echo "$as_me:1493: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_CC="$ac_tool_prefix$ac_prog" +echo "$as_me:1508: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1516: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1519: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:1532: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_CC="$ac_prog" +echo "$as_me:1547: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:1555: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:1558: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + +test -z "$CC" && { { echo "$as_me:1570: error: no acceptable cc found in \$PATH" >&5 +echo "$as_me: error: no acceptable cc found in \$PATH" >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:1575:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:1578: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:1581: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:1583: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:1586: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:1588: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:1591: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line 1595 "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe" +# 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. +echo "$as_me:1611: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:1614: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:1617: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. +for ac_file in `ls a.exe conftest.exe 2>/dev/null; + ls a.out conftest 2>/dev/null; + ls a.* conftest.* 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;; + a.out ) # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool --akim. + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:1640: error: C compiler cannot create executables" >&5 +echo "$as_me: error: C compiler cannot create executables" >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:1646: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:1651: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:1657: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1660: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:1667: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:1675: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:1682: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:1684: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:1687: checking for executable suffix" >&5 +echo $ECHO_N "checking for executable suffix... $ECHO_C" >&6 +if { (eval echo "$as_me:1689: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:1692: \$? = $ac_status" >&5 + (exit $ac_status); }; 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 `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:1708: error: cannot compute EXEEXT: cannot compile and link" >&5 +echo "$as_me: error: cannot compute EXEEXT: cannot compile and link" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:1714: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:1720: checking for object suffix" >&5 +echo $ECHO_N "checking for object suffix... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 1726 "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:1738: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1741: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:1753: error: cannot compute OBJEXT: cannot compile" >&5 +echo "$as_me: error: cannot compute OBJEXT: cannot compile" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:1760: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:1764: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 1770 "configure" +#include "confdefs.h" + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1785: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1788: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1791: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1794: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:1806: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:1812: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 1818 "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1830: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1833: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1836: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1839: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:1849: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$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 +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1876: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1879: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1882: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1885: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line 1897 "configure" +#include "confdefs.h" +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1910: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1913: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1916: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1919: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line 1929 "configure" +#include "confdefs.h" +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1941: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1944: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1947: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1950: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f 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 + +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 +echo "$as_me:1980: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" +echo "$as_me:1995: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:2003: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:2006: result: no" >&5 +echo "${ECHO_T}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 +echo "$as_me:2015: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_RANLIB="ranlib" +echo "$as_me:2030: found $ac_dir/$ac_word" >&5 +break +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:2039: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:2042: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +# 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" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:2063: checking for a BSD compatible install" >&5 +echo $ECHO_N "checking for a BSD compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_IFS=$IFS; IFS=$ac_path_separator + for ac_dir in $PATH; do + IFS=$ac_save_IFS + # Account for people who put trailing slashes in PATH elements. + case $ac_dir/ in + / | ./ | .// | /cC/* \ + | /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* \ + | /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 + if $as_executable_p "$ac_dir/$ac_prog"; then + if test $ac_prog = install && + grep dspmsg "$ac_dir/$ac_prog" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$ac_dir/$ac_prog" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + +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. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:2112: result: $INSTALL" >&5 +echo "${ECHO_T}$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' + +echo "$as_me:2123: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + echo "$as_me:2127: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:2130: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6 +fi + +# Check whether --with-rtsig or --without-rtsig was given. +if test "${with_rtsig+set}" = set; then + withval="$with_rtsig" + usertsig=yes +else + usertsig=no +fi; + +echo "$as_me:2142: checking for socket in -lsocket" >&5 +echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_socket+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line 2150 "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:2169: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:2172: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:2175: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2178: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_socket=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_socket_socket=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:2189: result: $ac_cv_lib_socket_socket" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6 +if test $ac_cv_lib_socket_socket = yes; then + cat >>confdefs.h <&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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. + # 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 >conftest.$ac_ext <<_ACEOF +#line 2226 "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:2231: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:2237: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line 2260 "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:2264: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:2270: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f 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 +echo "$as_me:2307: result: $CPP" >&5 +echo "${ECHO_T}$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. + # 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 >conftest.$ac_ext <<_ACEOF +#line 2317 "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:2322: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:2328: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line 2351 "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:2355: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:2361: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:2389: error: C preprocessor \"$CPP\" fails sanity check" >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;} + { (exit 1); exit 1; }; } +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 + +echo "$as_me:2400: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2406 "configure" +#include "confdefs.h" +#include +#include +#include +#include + +_ACEOF +if { (eval echo "$as_me:2414: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:2420: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line 2442 "configure" +#include "confdefs.h" +#include + +_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 >conftest.$ac_ext <<_ACEOF +#line 2460 "configure" +#include "confdefs.h" +#include + +_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 >conftest.$ac_ext <<_ACEOF +#line 2481 "configure" +#include "confdefs.h" +#include +#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)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:2507: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:2510: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:2512: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2515: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_header_stdc=no +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:2528: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +for ac_header in stdarg.h inttypes.h stdint.h poll.h signal.h unistd.h sys/epoll.h sys/time.h sys/queue.h sys/event.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:2541: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2547 "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:2551: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:2557: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_ext +fi +echo "$as_me:2576: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <&5 +echo $ECHO_N "checking for TAILQ_FOREACH in sys/queue.h... $ECHO_C" >&6 + cat >conftest.$ac_ext <<_ACEOF +#line 2590 "configure" +#include "confdefs.h" + +#include +#ifdef TAILQ_FOREACH + yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "yes" >/dev/null 2>&1; then + echo "$as_me:2601: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\EOF +#define HAVE_TAILQFOREACH 1 +EOF + +else + echo "$as_me:2609: result: no" >&5 +echo "${ECHO_T}no" >&6 + +fi +rm -f conftest* + +fi + +if test "x$ac_cv_header_sys_time_h" = "xyes"; then + echo "$as_me:2618: checking for timeradd in sys/time.h" >&5 +echo $ECHO_N "checking for timeradd in sys/time.h... $ECHO_C" >&6 + cat >conftest.$ac_ext <<_ACEOF +#line 2621 "configure" +#include "confdefs.h" + +#include +#ifdef timeradd + yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "yes" >/dev/null 2>&1; then + +cat >>confdefs.h <<\EOF +#define HAVE_TIMERADD 1 +EOF + + echo "$as_me:2637: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:2640: result: no" >&5 +echo "${ECHO_T}no" >&6 + +fi +rm -f conftest* + +fi + +echo "$as_me:2648: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2654 "configure" +#include "confdefs.h" +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2670: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2673: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2676: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2679: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_header_time=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:2689: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6 +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\EOF +#define TIME_WITH_SYS_TIME 1 +EOF + +fi + +for ac_func in gettimeofday vasprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:2702: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2708 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:2739: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:2742: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:2745: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2748: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:2758: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2780 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:2811: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:2814: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:2817: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2820: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:2830: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2857 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:2888: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:2891: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:2894: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2897: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:2907: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2932 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:2963: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:2966: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:2969: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2972: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:2982: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <&5 +echo $ECHO_N "checking for F_SETSIG in fcntl.h... $ECHO_C" >&6 + cat >conftest.$ac_ext <<_ACEOF +#line 2998 "configure" +#include "confdefs.h" + +#define _GNU_SOURCE +#include +#ifdef F_SETSIG +yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "yes" >/dev/null 2>&1; then + echo "$as_me:3010: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:3013: result: no" >&5 +echo "${ECHO_T}no" >&6; havertsig=no +fi +rm -f conftest* + +fi +if test "x$havertsig" = "xyes" ; then + +cat >>confdefs.h <<\EOF +#define HAVE_RTSIG 1 +EOF + + LIBOBJS="$LIBOBJS rtsig.$ac_objext" + echo "$as_me:3026: checking for working rtsig on pipes" >&5 +echo $ECHO_N "checking for working rtsig on pipes... $ECHO_C" >&6 + if test "$cross_compiling" = yes; then + { { echo "$as_me:3029: error: cannot run test program while cross compiling" >&5 +echo "$as_me: error: cannot run test program while cross compiling" >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line 3034 "configure" +#include "confdefs.h" + +#define _GNU_SOURCE +#include +#include +#include + +int sigio() +{ + exit(0); +} + +int main() +{ + int fd[2]; + + pipe(fd); + signal(SIGIO, sigio); + fcntl(fd[0], F_SETOWN, getpid()); + fcntl(fd[0], F_SETSIG, SIGIO); + fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL) | O_ASYNC); + write(fd[1], "", 1); + return 1; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:3062: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3065: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:3067: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3070: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + echo "$as_me:3072: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\EOF +#define HAVE_WORKING_RTSIG 1 +EOF + +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +echo "$as_me:3083: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi + +haveepoll=no + +for ac_func in epoll_ctl +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:3095: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3101 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3132: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3135: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3138: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3141: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:3151: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <>confdefs.h <<\EOF +#define HAVE_EPOLL 1 +EOF + + LIBOBJS="$LIBOBJS epoll.$ac_objext" + needsignal=yes +fi + +havekqueue=no +if test "x$ac_cv_header_sys_event_h" = "xyes"; then + +for ac_func in kqueue +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:3177: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3183 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3214: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3217: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3220: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3223: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:3233: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <&5 +echo $ECHO_N "checking for working kqueue... $ECHO_C" >&6 + if test "$cross_compiling" = yes; then + echo "$as_me:3247: result: no" >&5 +echo "${ECHO_T}no" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3251 "configure" +#include "confdefs.h" +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int kq; + int n; + int fd[2]; + struct kevent ev; + struct timespec ts; + char buf[8000]; + + if (pipe(fd) == -1) + exit(1); + if (fcntl(fd[1], F_SETFL, O_NONBLOCK) == -1) + exit(1); + + while ((n = write(fd[1], buf, sizeof(buf))) == sizeof(buf)) + ; + + if ((kq = kqueue()) == -1) + exit(1); + + ev.ident = fd[1]; + ev.filter = EVFILT_WRITE; + ev.flags = EV_ADD | EV_ENABLE; + n = kevent(kq, &ev, 1, NULL, 0, NULL); + if (n == -1) + exit(1); + + read(fd[0], buf, sizeof(buf)); + + ts.tv_sec = 0; + ts.tv_nsec = 0; + n = kevent(kq, NULL, 0, &ev, 1, &ts); + if (n == -1 || n == 0) + exit(1); + + exit(0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:3300: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3303: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:3305: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3308: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + echo "$as_me:3310: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\EOF +#define HAVE_WORKING_KQUEUE 1 +EOF + + LIBOBJS="$LIBOBJS kqueue.$ac_objext" +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +echo "$as_me:3322: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + fi +fi + +haveepollsyscall=no +if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then + if test "x$haveepoll" = "xno" ; then + echo "$as_me:3333: checking for epoll system call" >&5 +echo $ECHO_N "checking for epoll system call... $ECHO_C" >&6 + if test "$cross_compiling" = yes; then + echo "$as_me:3336: result: no" >&5 +echo "${ECHO_T}no" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3340 "configure" +#include "confdefs.h" +#include +#include +#include +#include +#include +#include + +int +epoll_create(int size) +{ + return (syscall(__NR_epoll_create, size)); +} + +int +main(int argc, char **argv) +{ + int epfd; + + epfd = epoll_create(256); + exit (epfd == -1 ? 1 : 0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:3365: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3368: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:3370: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3373: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + echo "$as_me:3375: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\EOF +#define HAVE_EPOLL 1 +EOF + + needsignal=yes + LIBOBJS="$LIBOBJS epoll_sub.$ac_objext" + LIBOBJS="$LIBOBJS epoll.$ac_objext" +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +echo "$as_me:3389: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + fi +fi + +if test "x$needsignal" = "xyes" ; then + LIBOBJS="$LIBOBJS signal.$ac_objext" +fi + +for ac_func in err +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:3404: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3410 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* 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_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3441: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3444: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3447: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3450: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:3460: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3484 "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3490: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:3493: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:3496: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3499: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:3509: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 +if test "${ac_cv_type_pid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3525 "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((pid_t *) 0) + return 0; +if (sizeof (pid_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3540: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:3543: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:3546: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3549: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_pid_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_pid_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:3559: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6 +if test $ac_cv_type_pid_t = yes; then + : +else + +cat >>confdefs.h <&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6 +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3577 "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((size_t *) 0) + return 0; +if (sizeof (size_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3592: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:3595: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:3598: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3601: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_size_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:3611: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <&5 +echo $ECHO_N "checking for u_int64_t... $ECHO_C" >&6 +if test "${ac_cv_type_u_int64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3629 "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((u_int64_t *) 0) + return 0; +if (sizeof (u_int64_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3644: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:3647: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:3650: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3653: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_u_int64_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_u_int64_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:3663: result: $ac_cv_type_u_int64_t" >&5 +echo "${ECHO_T}$ac_cv_type_u_int64_t" >&6 +if test $ac_cv_type_u_int64_t = yes; then + : +else + +cat >>confdefs.h <&5 +echo $ECHO_N "checking for u_int32_t... $ECHO_C" >&6 +if test "${ac_cv_type_u_int32_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3681 "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((u_int32_t *) 0) + return 0; +if (sizeof (u_int32_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3696: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:3699: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:3702: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3705: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_u_int32_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_u_int32_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:3715: result: $ac_cv_type_u_int32_t" >&5 +echo "${ECHO_T}$ac_cv_type_u_int32_t" >&6 +if test $ac_cv_type_u_int32_t = yes; then + : +else + +cat >>confdefs.h <&5 +echo $ECHO_N "checking for u_int16_t... $ECHO_C" >&6 +if test "${ac_cv_type_u_int16_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3733 "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((u_int16_t *) 0) + return 0; +if (sizeof (u_int16_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3748: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:3751: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:3754: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3757: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_u_int16_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_u_int16_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:3767: result: $ac_cv_type_u_int16_t" >&5 +echo "${ECHO_T}$ac_cv_type_u_int16_t" >&6 +if test $ac_cv_type_u_int16_t = yes; then + : +else + +cat >>confdefs.h <&5 +echo $ECHO_N "checking for u_int8_t... $ECHO_C" >&6 +if test "${ac_cv_type_u_int8_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3785 "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((u_int8_t *) 0) + return 0; +if (sizeof (u_int8_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3800: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:3803: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:3806: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3809: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_u_int8_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_u_int8_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:3819: result: $ac_cv_type_u_int8_t" >&5 +echo "${ECHO_T}$ac_cv_type_u_int8_t" >&6 +if test $ac_cv_type_u_int8_t = yes; then + : +else + +cat >>confdefs.h <&5 +echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line 3834 "configure" +#include "confdefs.h" + + #include + #include +int +main () +{ +socklen_t x; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3848: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:3851: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:3854: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3857: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + echo "$as_me:3859: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +echo "$as_me:3864: result: no" >&5 +echo "${ECHO_T}no" >&6 + +cat >>confdefs.h <<\EOF +#define socklen_t unsigned int +EOF + +fi +rm -f conftest.$ac_objext conftest.$ac_ext + +ac_config_files="$ac_config_files Makefile test/Makefile sample/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 overriden 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, don't put newlines in cache variables' values. +# 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. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *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 \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if cmp -s $cache_file confcache; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + 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}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ 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[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:3954: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated automatically by configure. +# 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 +SHELL=\${CONFIG_SHELL-$SHELL} +ac_cs_invocation="\$0 \$@" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Name of the executable. +as_me=`echo "$0" |sed 's,.*[\\/],,'` + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +# NLS nuisances. +$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; } +$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; } +$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; } +$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; } +$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; } +$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; } +$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; } +$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; } + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; } + +exec 6>&1 + +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\EOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -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 + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." +EOF + +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + shift + set dummy "$ac_option" "$ac_optarg" ${1+"$@"} + shift + ;; + -*);; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_need_defaults=false;; + esac + + case $1 in + # Handling of the options. +EOF +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:4130: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + shift + CONFIG_FILES="$CONFIG_FILES $1" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + shift + CONFIG_HEADERS="$CONFIG_HEADERS $1" + ac_need_defaults=false;; + + # This is an error. + -*) { { echo "$as_me:4149: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +exec 5>>config.log +cat >&5 << _ACEOF + +## ----------------------- ## +## Running config.status. ## +## ----------------------- ## + +This file was extended by $as_me 2.52, executed with + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + > $ac_cs_invocation +on `(hostname || uname -n) 2>/dev/null | sed 1q` + +_ACEOF +EOF + +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "test/Makefile" ) CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + "sample/Makefile" ) CONFIG_FILES="$CONFIG_FILES sample/Makefile" ;; + "default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:4196: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + 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_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/cs$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + +EOF + +cat >>$CONFIG_STATUS <\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@DEFS@,$DEFS,;t t +s,@LIBS@,$LIBS,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t +s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t +s,@MAINT@,$MAINT,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@LN_S@,$LN_S,;t t +s,@CPP@,$CPP,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +CEOF + +EOF + + cat >>$CONFIG_STATUS <<\EOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +EOF +cat >>$CONFIG_STATUS <<\EOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + { case "$ac_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || mkdir "$as_incr_dir" + ;; + esac +done; } + + ac_dir_suffix="/`echo $ac_dir|sed 's,^\./,,'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo "$ac_dir_suffix" | sed 's,/[^/]*,../,g'` + else + ac_dir_suffix= ac_dots= + fi + + case $srcdir in + .) ac_srcdir=. + if test -z "$ac_dots"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_dots | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_dots$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_dots$srcdir ;; + esac + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_dots$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:4418: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # 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 automatically by config.status. */ + configure_input="Generated automatically from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:4436: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:4449: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +EOF +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +EOF +cat >>$CONFIG_STATUS <<\EOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:4510: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:4521: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:4534: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +EOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\EOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\(\([^ (][^ (]*\)([^)]*)\)[ ]*\(.*\)$,${ac_dA}\2${ac_dB}\1${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +EOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\EOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +EOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if egrep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # egrep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\EOF + # 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 automatically by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated automatically by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated automatically by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if cmp -s $ac_file $tmp/config.h 2>/dev/null; then + { echo "$as_me:4651: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + { case "$ac_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || mkdir "$as_incr_dir" + ;; + esac +done; } + + fi + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +EOF +cat >>$CONFIG_STATUS <<\EOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + + case $ac_dest in + default-1 ) test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h ;; + esac +done +EOF + +cat >>$CONFIG_STATUS <<\EOF + +{ (exit 0); exit 0; } +EOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + +# 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=: + exec 5>/dev/null + $SHELL $CONFIG_STATUS || 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 || { (exit 1); exit 1; } +fi + diff --git a/libevent/configure.in b/libevent/configure.in new file mode 100644 index 0000000..7a10f58 --- /dev/null +++ b/libevent/configure.in @@ -0,0 +1,253 @@ +dnl configure.in for libevent +dnl Dug Song +AC_INIT(event.c) + +AM_INIT_AUTOMAKE(libevent,0.8) +AM_CONFIG_HEADER(config.h) +AM_MAINTAINER_MODE + +dnl Initialize prefix. +if test "$prefix" = "NONE"; then + prefix="/usr/local" +fi + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_RANLIB +AC_PROG_INSTALL +AC_PROG_LN_S + +dnl Check for optional stuff +AC_ARG_WITH(rtsig, + [ --with-rtsig compile with support for real time signals (experimental)], + [usertsig=yes], [usertsig=no]) + +dnl Checks for libraries. +AC_CHECK_LIB(socket, socket) + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(stdarg.h inttypes.h stdint.h poll.h signal.h unistd.h sys/epoll.h sys/time.h sys/queue.h sys/event.h) +if test "x$ac_cv_header_sys_queue_h" = "xyes"; then + AC_MSG_CHECKING(for TAILQ_FOREACH in sys/queue.h) + AC_EGREP_CPP(yes, +[ +#include +#ifdef TAILQ_FOREACH + yes +#endif +], [AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_TAILQFOREACH, 1, + [Define if TAILQ_FOREACH is defined in ])], + AC_MSG_RESULT(no) + ) +fi + +if test "x$ac_cv_header_sys_time_h" = "xyes"; then + AC_MSG_CHECKING(for timeradd in sys/time.h) + AC_EGREP_CPP(yes, +[ +#include +#ifdef timeradd + yes +#endif +], [ AC_DEFINE(HAVE_TIMERADD, 1, + [Define if timeradd is defined in ]) + AC_MSG_RESULT(yes)] ,AC_MSG_RESULT(no) +) +fi + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_TIME + +dnl Checks for library functions. +AC_CHECK_FUNCS(gettimeofday vasprintf) + +needsignal=no +haveselect=no +AC_CHECK_FUNCS(select, [haveselect=yes], ) +if test "x$haveselect" = "xyes" ; then + AC_LIBOBJ(select) + needsignal=yes +fi + +havepoll=no +havertsig=no +AC_CHECK_FUNCS(poll, [havepoll=yes], ) +if test "x$havepoll" = "xyes" ; then + AC_LIBOBJ(poll) + needsignal=yes + + if test "x$usertsig" = "xyes" ; then + AC_CHECK_FUNCS(sigtimedwait, [havertsig=yes], ) + fi +fi +if test "x$havertsig" = "xyes" ; then + AC_MSG_CHECKING(for F_SETSIG in fcntl.h) + AC_EGREP_CPP(yes, +[ +#define _GNU_SOURCE +#include +#ifdef F_SETSIG +yes +#endif +], [ AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no); havertsig=no]) +fi +if test "x$havertsig" = "xyes" ; then + AC_DEFINE(HAVE_RTSIG, 1, [Define if your system supports POSIX realtime signals]) + AC_LIBOBJ(rtsig) + AC_MSG_CHECKING(for working rtsig on pipes) + AC_TRY_RUN( +[ +#define _GNU_SOURCE +#include +#include +#include + +int sigio() +{ + exit(0); +} + +int main() +{ + int fd[2]; + + pipe(fd); + signal(SIGIO, sigio); + fcntl(fd[0], F_SETOWN, getpid()); + fcntl(fd[0], F_SETSIG, SIGIO); + fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL) | O_ASYNC); + write(fd[1], "", 1); + return 1; +} +], [ AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_WORKING_RTSIG, 1, [Define if realtime signals work on pipes])], + AC_MSG_RESULT(no)) +fi + +haveepoll=no +AC_CHECK_FUNCS(epoll_ctl, [haveepoll=yes], ) +if test "x$haveepoll" = "xyes" ; then + AC_DEFINE(HAVE_EPOLL, 1, + [Define if your system supports the epoll system calls]) + AC_LIBOBJ(epoll) + needsignal=yes +fi + +havekqueue=no +if test "x$ac_cv_header_sys_event_h" = "xyes"; then + AC_CHECK_FUNCS(kqueue, [havekqueue=yes], ) + if test "x$havekqueue" = "xyes" ; then + AC_MSG_CHECKING(for working kqueue) + AC_TRY_RUN( +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int kq; + int n; + int fd[[2]]; + struct kevent ev; + struct timespec ts; + char buf[[8000]]; + + if (pipe(fd) == -1) + exit(1); + if (fcntl(fd[[1]], F_SETFL, O_NONBLOCK) == -1) + exit(1); + + while ((n = write(fd[[1]], buf, sizeof(buf))) == sizeof(buf)) + ; + + if ((kq = kqueue()) == -1) + exit(1); + + ev.ident = fd[[1]]; + ev.filter = EVFILT_WRITE; + ev.flags = EV_ADD | EV_ENABLE; + n = kevent(kq, &ev, 1, NULL, 0, NULL); + if (n == -1) + exit(1); + + read(fd[[0]], buf, sizeof(buf)); + + ts.tv_sec = 0; + ts.tv_nsec = 0; + n = kevent(kq, NULL, 0, &ev, 1, &ts); + if (n == -1 || n == 0) + exit(1); + + exit(0); +}, [AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_WORKING_KQUEUE, 1, + [Define if kqueue works correctly with pipes]) + AC_LIBOBJ(kqueue)], AC_MSG_RESULT(no), AC_MSG_RESULT(no)) + fi +fi + +haveepollsyscall=no +if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then + if test "x$haveepoll" = "xno" ; then + AC_MSG_CHECKING(for epoll system call) + AC_TRY_RUN( +#include +#include +#include +#include +#include +#include + +int +epoll_create(int size) +{ + return (syscall(__NR_epoll_create, size)); +} + +int +main(int argc, char **argv) +{ + int epfd; + + epfd = epoll_create(256); + exit (epfd == -1 ? 1 : 0); +}, [AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_EPOLL, 1, + [Define if your system supports the epoll system calls]) + needsignal=yes + AC_LIBOBJ(epoll_sub) + AC_LIBOBJ(epoll)], AC_MSG_RESULT(no), AC_MSG_RESULT(no)) + fi +fi + +if test "x$needsignal" = "xyes" ; then + AC_LIBOBJ(signal) +fi + +AC_REPLACE_FUNCS(err) + +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_CHECK_TYPE(u_int64_t, unsigned long long) +AC_CHECK_TYPE(u_int32_t, unsigned int) +AC_CHECK_TYPE(u_int16_t, unsigned short) +AC_CHECK_TYPE(u_int8_t, unsigned char) + +AC_MSG_CHECKING([for socklen_t]) +AC_TRY_COMPILE([ + #include + #include ], + [socklen_t x;], + AC_MSG_RESULT([yes]), + [AC_MSG_RESULT([no]) + AC_DEFINE(socklen_t, unsigned int, + [Define to unsigned int if you dont have it])] +) + +AC_OUTPUT(Makefile test/Makefile sample/Makefile) diff --git a/libevent/epoll.c b/libevent/epoll.c new file mode 100644 index 0000000..a3a35f3 --- /dev/null +++ b/libevent/epoll.c @@ -0,0 +1,335 @@ +/* + * Copyright 2000-2003 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#ifdef HAVE_SYS_TIME_H +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_LOG +#include "log.h" +#else +#define LOG_DBG(x) +#define log_error warn +#endif + +#include "event.h" +#include "evsignal.h" + +extern struct event_list eventqueue; + +extern volatile sig_atomic_t evsignal_caught; + +/* due to limitations in the epoll interface, we need to keep track of + * all file descriptors outself. + */ +struct evepoll { + struct event *evread; + struct event *evwrite; +}; + +struct epollop { + struct evepoll *fds; + int nfds; + struct epoll_event *events; + int nevents; + int epfd; + sigset_t evsigmask; +} epollop; + +void *epoll_init (void); +int epoll_add (void *, struct event *); +int epoll_del (void *, struct event *); +int epoll_recalc (void *, int); +int epoll_dispatch (void *, struct timeval *); + +struct eventop epollops = { + "epoll", + epoll_init, + epoll_add, + epoll_del, + epoll_recalc, + epoll_dispatch +}; + +#define NEVENT 32000 + +void * +epoll_init(void) +{ + int epfd, nfiles = NEVENT; + struct rlimit rl; + + /* Disable epollueue when this environment variable is set */ + if (getenv("EVENT_NOEPOLL")) + return (NULL); + + memset(&epollop, 0, sizeof(epollop)); + + if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && + rl.rlim_cur != RLIM_INFINITY) + nfiles = rl.rlim_cur; + + /* Initalize the kernel queue */ + + if ((epfd = epoll_create(nfiles)) == -1) { + log_error("epoll_create"); + return (NULL); + } + + epollop.epfd = epfd; + + /* Initalize fields */ + epollop.events = malloc(nfiles * sizeof(struct epoll_event)); + if (epollop.events == NULL) + return (NULL); + epollop.nevents = nfiles; + + epollop.fds = calloc(nfiles, sizeof(struct evepoll)); + if (epollop.fds == NULL) { + free(epollop.events); + return (NULL); + } + epollop.nfds = nfiles; + + evsignal_init(&epollop.evsigmask); + + return (&epollop); +} + +int +epoll_recalc(void *arg, int max) +{ + struct epollop *epollop = arg; + + if (max > epollop->nfds) { + struct evepoll *fds; + int nfds; + + nfds = epollop->nfds; + while (nfds < max) + nfds <<= 1; + + fds = realloc(epollop->fds, nfds * sizeof(struct evepoll)); + if (fds == NULL) { + log_error("realloc"); + return (-1); + } + epollop->fds = fds; + memset(fds + epollop->nfds, 0, + (nfds - epollop->nfds) * sizeof(struct evepoll)); + epollop->nfds = nfds; + } + + return (evsignal_recalc(&epollop->evsigmask)); +} + +int +epoll_dispatch(void *arg, struct timeval *tv) +{ + struct epollop *epollop = arg; + struct epoll_event *events = epollop->events; + struct evepoll *evep; + int i, res, timeout; + + if (evsignal_deliver(&epollop->evsigmask) == -1) + return (-1); + + timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; + res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout); + + if (evsignal_recalc(&epollop->evsigmask) == -1) + return (-1); + + if (res == -1) { + if (errno != EINTR) { + log_error("epoll_wait"); + return (-1); + } + + evsignal_process(); + return (0); + } else if (evsignal_caught) + evsignal_process(); + + LOG_DBG((LOG_MISC, 80, "%s: epoll_wait reports %d", __func__, res)); + + for (i = 0; i < res; i++) { + int which = 0; + int what = events[i].events; + struct event *evread = NULL, *evwrite = NULL; + + evep = (struct evepoll *)events[i].data.ptr; + + if (what & EPOLLHUP) + what |= EPOLLIN | EPOLLOUT; + else if (what & EPOLLERR) + what |= EPOLLIN | EPOLLOUT; + + if (what & EPOLLIN) { + evread = evep->evread; + which |= EV_READ; + } + + if (what & EPOLLOUT) { + evwrite = evep->evwrite; + which |= EV_WRITE; + } + + if (!which) + continue; + + if (evread != NULL && !(evread->ev_events & EV_PERSIST)) + event_del(evread); + if (evwrite != NULL && evwrite != evread && + !(evwrite->ev_events & EV_PERSIST)) + event_del(evwrite); + + if (evread != NULL) + event_active(evread, EV_READ, 1); + if (evwrite != NULL) + event_active(evwrite, EV_WRITE, 1); + } + + return (0); +} + + +int +epoll_add(void *arg, struct event *ev) +{ + struct epollop *epollop = arg; + struct epoll_event epev; + struct evepoll *evep; + int fd, op, events; + + if (ev->ev_events & EV_SIGNAL) + return (evsignal_add(&epollop->evsigmask, ev)); + + fd = ev->ev_fd; + if (fd >= epollop->nfds) { + /* Extent the file descriptor array as necessary */ + if (epoll_recalc(epollop, fd) == -1) + return (-1); + } + evep = &epollop->fds[fd]; + op = EPOLL_CTL_ADD; + events = 0; + if (evep->evread != NULL) { + events |= EPOLLIN; + op = EPOLL_CTL_MOD; + } + if (evep->evwrite != NULL) { + events |= EPOLLOUT; + op = EPOLL_CTL_MOD; + } + + if (ev->ev_events & EV_READ) + events |= EPOLLIN; + if (ev->ev_events & EV_WRITE) + events |= EPOLLOUT; + + epev.data.ptr = evep; + epev.events = events; + if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) + return (-1); + + /* Update events responsible */ + if (ev->ev_events & EV_READ) + evep->evread = ev; + if (ev->ev_events & EV_WRITE) + evep->evwrite = ev; + + return (0); +} + +int +epoll_del(void *arg, struct event *ev) +{ + struct epollop *epollop = arg; + struct epoll_event epev; + struct evepoll *evep; + int fd, events, op; + int needwritedelete = 1, needreaddelete = 1; + + if (ev->ev_events & EV_SIGNAL) + return (evsignal_del(&epollop->evsigmask, ev)); + + fd = ev->ev_fd; + if (fd >= epollop->nfds) + return (0); + evep = &epollop->fds[fd]; + + op = EPOLL_CTL_DEL; + events = 0; + + if (ev->ev_events & EV_READ) + events |= EPOLLIN; + if (ev->ev_events & EV_WRITE) + events |= EPOLLOUT; + + if ((events & (EPOLLIN|EPOLLOUT)) != (EPOLLIN|EPOLLOUT)) { + if ((events & EPOLLIN) && evep->evwrite != NULL) { + needwritedelete = 0; + events = EPOLLOUT; + op = EPOLL_CTL_MOD; + } else if ((events & EPOLLOUT) && evep->evread != NULL) { + needreaddelete = 0; + events = EPOLLIN; + op = EPOLL_CTL_MOD; + } + } + + epev.events = events; + epev.data.ptr = evep; + + if (epoll_ctl(epollop->epfd, op, fd, &epev) == -1) + return (-1); + + if (needreaddelete) + evep->evread = NULL; + if (needwritedelete) + evep->evwrite = NULL; + + return (0); +} diff --git a/libevent/epoll_sub.c b/libevent/epoll_sub.c new file mode 100644 index 0000000..431970c --- /dev/null +++ b/libevent/epoll_sub.c @@ -0,0 +1,52 @@ +/* + * Copyright 2003 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#include + +#include +#include +#include +#include +#include + +int +epoll_create(int size) +{ + return (syscall(__NR_epoll_create, size)); +} + +int +epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) +{ + + return (syscall(__NR_epoll_ctl, epfd, op, fd, event)); +} + +int +epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) +{ + return (syscall(__NR_epoll_wait, epfd, events, maxevents, timeout)); +} diff --git a/libevent/err.c b/libevent/err.c new file mode 100644 index 0000000..4fc03c1 --- /dev/null +++ b/libevent/err.c @@ -0,0 +1,97 @@ +/* $OpenBSD: err.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */ + +/* + * err.c + * + * Adapted from OpenBSD libc *err* *warn* code. + * + * Copyright (c) 2000 Dug Song + * + * Copyright (c) 1993 + * The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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. + */ + +#include +#include +#include +#include +#include + +void +err(int eval, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) { + (void)vfprintf(stderr, fmt, ap); + (void)fprintf(stderr, ": "); + } + va_end(ap); + (void)fprintf(stderr, "%s\n", strerror(errno)); + exit(eval); +} + +void +warn(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) { + (void)vfprintf(stderr, fmt, ap); + (void)fprintf(stderr, ": "); + } + va_end(ap); + (void)fprintf(stderr, "%s\n", strerror(errno)); +} + +void +errx(int eval, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) + (void)vfprintf(stderr, fmt, ap); + (void)fprintf(stderr, "\n"); + va_end(ap); + exit(eval); +} + +void +warnx(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) + (void)vfprintf(stderr, fmt, ap); + (void)fprintf(stderr, "\n"); + va_end(ap); +} + diff --git a/libevent/evbuffer.c b/libevent/evbuffer.c new file mode 100644 index 0000000..0e7481e --- /dev/null +++ b/libevent/evbuffer.c @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2002-2004 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#include +#include +#include +#include +#include +#ifdef HAVE_STDARG_H +#include +#endif + +#include "event.h" + +static int +bufferevent_add(struct event *ev, int timeout) +{ + struct timeval tv, *ptv = NULL; + + if (timeout) { + timerclear(&tv); + tv.tv_sec = timeout; + ptv = &tv; + } + + return (event_add(ev, ptv)); +} + +/* + * This callback is executed when the size of the input buffer changes. + * We use it to apply back pressure on the reading side. + */ + +void +bufferevent_read_pressure_cb(struct evbuffer *buf, size_t old, size_t now, + void *arg) { + struct bufferevent *bufev = arg; + /* + * If we are below the watermak then reschedule reading if it's + * still enabled. + */ + if (bufev->wm_read.high == 0 || now < bufev->wm_read.high) { + evbuffer_setcb(buf, NULL, NULL); + + if (bufev->enabled & EV_READ) + bufferevent_add(&bufev->ev_read, bufev->timeout_read); + } +} + +static void +bufferevent_readcb(int fd, short event, void *arg) +{ + struct bufferevent *bufev = arg; + int res = 0; + short what = EVBUFFER_READ; + size_t len; + + if (event == EV_TIMEOUT) { + what |= EVBUFFER_TIMEOUT; + goto error; + } + + res = evbuffer_read(bufev->input, fd, -1); + if (res == -1) { + if (errno == EAGAIN || errno == EINTR) + goto reschedule; + /* error case */ + what |= EVBUFFER_ERROR; + } else if (res == 0) { + /* eof case */ + what |= EVBUFFER_EOF; + } + + if (res <= 0) + goto error; + + bufferevent_add(&bufev->ev_read, bufev->timeout_read); + + /* See if this callbacks meets the water marks */ + len = EVBUFFER_LENGTH(bufev->input); + if (bufev->wm_read.low != 0 && len < bufev->wm_read.low) + return; + if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) { + struct evbuffer *buf = bufev->input; + event_del(&bufev->ev_read); + + /* Now schedule a callback for us */ + evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev); + return; + } + + /* Invoke the user callback - must always be called last */ + (*bufev->readcb)(bufev, bufev->cbarg); + return; + + reschedule: + bufferevent_add(&bufev->ev_read, bufev->timeout_read); + return; + + error: + (*bufev->errorcb)(bufev, what, bufev->cbarg); +} + +static void +bufferevent_writecb(int fd, short event, void *arg) +{ + struct bufferevent *bufev = arg; + int res = 0; + short what = EVBUFFER_WRITE; + + if (event == EV_TIMEOUT) { + what |= EVBUFFER_TIMEOUT; + goto error; + } + + if (EVBUFFER_LENGTH(bufev->output)) { + res = evbuffer_write(bufev->output, fd); + if (res == -1) { + if (errno == EAGAIN || errno == EINTR) + goto reschedule; + /* error case */ + what |= EVBUFFER_ERROR; + } else if (res == 0) { + /* eof case */ + what |= EVBUFFER_EOF; + } + if (res <= 0) + goto error; + } + + if (EVBUFFER_LENGTH(bufev->output) != 0) + bufferevent_add(&bufev->ev_write, bufev->timeout_write); + + /* + * Invoke the user callback if our buffer is drained or below the + * low watermark. + */ + if (EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low) + (*bufev->writecb)(bufev, bufev->cbarg); + + return; + + reschedule: + if (EVBUFFER_LENGTH(bufev->output) != 0) + bufferevent_add(&bufev->ev_write, bufev->timeout_write); + return; + + error: + (*bufev->errorcb)(bufev, what, bufev->cbarg); +} + +/* + * Create a new buffered event object. + * + * The read callback is invoked whenever we read new data. + * The write callback is invoked whenever the output buffer is drained. + * The error callback is invoked on a write/read error or on EOF. + */ + +struct bufferevent * +bufferevent_new(int fd, evbuffercb readcb, evbuffercb writecb, + everrorcb errorcb, void *cbarg) +{ + struct bufferevent *bufev; + + if ((bufev = calloc(1, sizeof(struct bufferevent))) == NULL) + return (NULL); + + if ((bufev->input = evbuffer_new()) == NULL) { + free(bufev); + return (NULL); + } + + if ((bufev->output = evbuffer_new()) == NULL) { + evbuffer_free(bufev->input); + free(bufev); + return (NULL); + } + + event_set(&bufev->ev_read, fd, EV_READ, bufferevent_readcb, bufev); + event_set(&bufev->ev_write, fd, EV_WRITE, bufferevent_writecb, bufev); + + bufev->readcb = readcb; + bufev->writecb = writecb; + bufev->errorcb = errorcb; + + bufev->cbarg = cbarg; + + bufev->enabled = EV_READ | EV_WRITE; + + return (bufev); +} + +void +bufferevent_free(struct bufferevent *bufev) +{ + event_del(&bufev->ev_read); + event_del(&bufev->ev_write); + + evbuffer_free(bufev->input); + evbuffer_free(bufev->output); + + free(bufev); +} + +/* + * Returns 0 on success; + * -1 on failure. + */ + +int +bufferevent_write(struct bufferevent *bufev, void *data, size_t size) +{ + int res; + + res = evbuffer_add(bufev->output, data, size); + + if (res == -1) + return (res); + + /* If everything is okay, we need to schedule a write */ + if (size > 0 && (bufev->enabled & EV_WRITE)) + bufferevent_add(&bufev->ev_write, bufev->timeout_write); + + return (res); +} + +int +bufferevent_write_buffer(struct bufferevent *bufev, struct evbuffer *buf) +{ + int res; + + res = bufferevent_write(bufev, buf->buffer, buf->off); + if (res != -1) + evbuffer_drain(buf, buf->off); + + return (res); +} + +size_t +bufferevent_read(struct bufferevent *bufev, void *data, size_t size) +{ + struct evbuffer *buf = bufev->input; + + if (buf->off < size) + size = buf->off; + + /* Copy the available data to the user buffer */ + memcpy(data, buf->buffer, size); + + if (size) + evbuffer_drain(buf, size); + + return (size); +} + +int +bufferevent_enable(struct bufferevent *bufev, short event) +{ + if (event & EV_READ) { + if (bufferevent_add(&bufev->ev_read, bufev->timeout_read) == -1) + return (-1); + } + if (event & EV_WRITE) { + if (bufferevent_add(&bufev->ev_write, bufev->timeout_write) == -1) + return (-1); + } + + bufev->enabled |= event; + return (0); +} + +int +bufferevent_disable(struct bufferevent *bufev, short event) +{ + if (event & EV_READ) { + if (event_del(&bufev->ev_read) == -1) + return (-1); + } + if (event & EV_WRITE) { + if (event_del(&bufev->ev_write) == -1) + return (-1); + } + + bufev->enabled &= ~event; + return (0); +} + +/* + * Sets the read and write timeout for a buffered event. + */ + +void +bufferevent_settimeout(struct bufferevent *bufev, + int timeout_read, int timeout_write) { + bufev->timeout_read = timeout_read; + bufev->timeout_write = timeout_write; +} + +/* + * Sets the water marks + */ + +void +bufferevent_setwatermark(struct bufferevent *bufev, short events, + size_t lowmark, size_t highmark) +{ + if (events & EV_READ) { + bufev->wm_read.low = lowmark; + bufev->wm_read.high = highmark; + } + + if (events & EV_WRITE) { + bufev->wm_write.low = lowmark; + bufev->wm_write.high = highmark; + } + + /* If the watermarks changed then see if we should call read again */ + bufferevent_read_pressure_cb(bufev->input, + 0, EVBUFFER_LENGTH(bufev->input), bufev); +} diff --git a/libevent/event.3 b/libevent/event.3 new file mode 100644 index 0000000..687a6f4 --- /dev/null +++ b/libevent/event.3 @@ -0,0 +1,444 @@ +.\" $OpenBSD: event.3,v 1.4 2002/07/12 18:50:48 provos Exp $ +.\" +.\" Copyright (c) 2000 Artur Grabowski +.\" 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. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED ``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. +.\" +.Dd August 8, 2000 +.Dt EVENT 3 +.Os +.Sh NAME +.Nm event_init , +.Nm event_dispatch , +.Nm event_loop , +.Nm event_loopexit , +.Nm event_set , +.Nm event_add , +.Nm event_del , +.Nm event_once , +.Nm event_pending , +.Nm event_initialized , +.Nm evtimer_set , +.Nm evtimer_add , +.Nm evtimer_del +.Nm evtimer_pending , +.Nm evtimer_initialized , +.Nm signal_set , +.Nm signal_add , +.Nm signal_del +.Nm signal_pending , +.Nm signal_initialized , +.Nm bufferevent_new , +.Nm bufferevent_free , +.Nm bufferevent_write , +.Nm bufferevent_write_buffer , +.Nm bufferevent_read , +.Nm bufferevent_enable , +.Nm bufferevent_disable , +.Nm bufferevent_settimeout , +.Nm evbuffer_new , +.Nm evbuffer_free , +.Nm evbuffer_add , +.Nm evbuffer_add_buffer , +.Nm evbuffer_add_printf , +.Nm evbuffer_drain , +.Nm evbuffer_write , +.Nm evbuffer_read , +.Nm evbuffer_find +.Nd execute a function when a specific event occurs +.Sh SYNOPSIS +.Fd #include +.Fd #include +.Ft void +.Fn "event_init" +.Ft int +.Fn "event_dispatch" +.Ft int +.Fn "event_loop" "int flags" +.Ft int +.Fn "event_loopexit" "struct timeval *tv" +.Ft void +.Fn "event_set" "struct event *ev" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" +.Ft int +.Fn "event_add" "struct event *ev" "struct timeval *tv" +.Ft int +.Fn "event_del" "struct event *ev" +.Ft int +.Fn "event_once" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "struct timeval *tv" +.Ft int +.Fn "event_pending" "struct event *ev" "short event" "struct timeval *tv" +.Ft int +.Fn "event_initialized" "struct event *ev" +.Ft void +.Fn "evtimer_set" "struct event *ev" "void (*fn)(int, short, void *)" "void *arg" +.Ft void +.Fn "evtimer_add" "struct event *ev" "struct timeval *" +.Ft void +.Fn "evtimer_del" "struct event *ev" +.Ft int +.Fn "evtimer_pending" "struct event *ev" "struct timeval *tv" +.Ft int +.Fn "evtimer_initialized" "struct event *ev" +.Ft void +.Fn "signal_set" "struct event *ev" "int signal" "void (*fn)(int, short, void *)" "void *arg" +.Ft void +.Fn "signal_add" "struct event *ev" "struct timeval *" +.Ft void +.Fn "signal_del" "struct event *ev" +.Ft int +.Fn "signal_pending" "struct event *ev" "struct timeval *tv" +.Ft int +.Fn "signal_initialized" "struct event *ev" +.Ft "struct bufferevent *" +.Fn "bufferevent_new" "int fd" "evbuffercb readcb" "evbuffercb writecb" "everrorcb" "void *cbarg" +.Ft void +.Fn "bufferevent_free" "struct bufferevent *bufev" +.Ft int +.Fn "bufferevent_write" "struct bufferevent *bufev" "void *data" "size_t size" +.Ft int +.Fn "bufferevent_write_buffer" "struct bufferevent *bufev" "struct evbuffer *buf" +.Ft size_t +.Fn "bufferevent_read" "struct bufferevent *bufev" "void *data" "size_t size" +.Ft int +.Fn "bufferevent_enable" "struct bufferevent *bufev" "short event" +.Ft int +.Fn "bufferevent_disable" "struct bufferevent *bufev" "short event" +.Ft void +.Fn "bufferevent_settimeout" "struct bufferevent *bufev" "int timeout_read" "int timeout_write" +.Ft "struct evbuffer *" +.Fn "evbuffer_new" "void" +.Ft void +.Fn "evbuffer_free" "struct evbuffer *buf" +.Ft int +.Fn "evbuffer_add" "struct evbuffer *buf" "u_char *data" "size_t size" +.Ft int +.Fn "evbuffer_add_buffer" "struct evbuffer *dst" "struct evbuffer *src" +.Ft int +.Fn "evbuffer_add_printf" "struct evbuffer *buf" "char *fmt" "..." +.Ft void +.Fn "evbuffer_drain" "struct evbuffer *buf" "size_t size" +.Ft int +.Fn "evbuffer_write" "struct evbuffer *buf" "int fd" +.Ft int +.Fn "evbuffer_read" "struct evbuffer *buf" "int fd" "int size" +.Ft "u_char *" +.Fn "evbuffer_find" "struct evbuffer *buf" "u_char *data" "size_t size" +.Ft int +.Fa (*event_sigcb)(void) ; +.Ft int +.Fa event_gotsig ; +.Sh DESCRIPTION +The +.Nm event +API provides a mechanism to execute a function when a specific event +on a file descriptor occurs or after a given time has passed. +.Pp +The +.Nm event +API needs to be initialized with +.Fn event_init +before it can be used. +.Pp +In order to process events, an application needs to call +.Fn event_dispatch . +This function only returns on error, and should replace the event core +of the application program. +.Pp +In order to avoid races in signal handlers, the +.Nm event +API provides two variables: +.Va event_sigcb +and +.Va event_gotsig . +A signal handler +sets +.Va event_gotsig +to indicate that a signal has been received. +The application sets +.Va event_sigcb +to a callback function. After the signal handler sets +.Va event_gotsig , +.Nm event_dispatch +will execute the callback function to process received signals. The +callback returns 1 when no events are registered any more. It can +return -1 to indicate an error to the +.Nm event +library, causing +.Fn event_dispatch +to terminate with +.Va errno +set to +.Er EINTR. +.Pp +The +.Nm event_loop +function provides an interface for single pass execution of pending +events. The flags +.Va EVLOOP_ONCE +and +.Va EVLOOP_NONBLOCK +are recognized. +The +.Nm event_loopexit +function allows the loop to be terminated after some amount of time +has passed. +The parameter indicates the time after which the loop should terminate. +.Pp +It is the responsibility of the caller to provide these functions with +pre-allocated event structures. +.Pp +The function +.Fn event_set +prepares the event structure +.Fa ev +to be used in future calls to +.Fn event_add +and +.Fn event_del . +The event will be prepared to call the function specified by the +.Fa fn +argument with an +.Fa int +argument indicating the file descriptor, a +.Fa short +argument indicating the type of event, and a +.Fa void * +argument given in the +.Fa arg +argument. +The +.Fa fd +indicates the file descriptor that should be monitored for events. +The events can be either +.Va EV_READ , +.Va EV_WRITE , +or both. +Indicating that an application can read or write from the file descriptor +respectively without blocking. +.Pp +The function +.Fa fn +will be called with the file descriptor that triggered the event and +the type of event which will be either +.Va EV_TIMEOUT , +.Va EV_SIGNAL , +.Va EV_READ , +or +.Va EV_WRITE . +The additional flag +.Va EV_PERSIST +makes an +.Fn event_add +persistent until +.Fn event_del +has been called. +.Pp +Once initialized, the +.Fa ev +structure can be used repeatedly with +.Fn event_add +and +.Fn event_del +and does not need to be reinitialized unless the function called and/or +the argument to it are to be changed. +.Pp +The function +.Fn event_add +schedules the execution of the +.Fa ev +event when the event specified in +.Fn event_set +occurs or in at least the time specified in the +.Fa tv . +If +.Fa tv +is NULL, no timeout occurs and the function will only be called +if a matching event occurs on the file descriptor. +The event in the +.Fa ev +argument must be already initialized by +.Fn event_set +and may not be used in calls to +.Fn event_set +until it has timed out or been removed with +.Fn event_del . +If the event in the +.Fa ev +argument already has a scheduled timeout, the old timeout will be +replaced by the new one. +.Pp +The function +.Fn event_del +will cancel the event in the argument +.Fa ev . +If the event has already executed or has never been added +the call will have no effect. +.Pp +The function +.Fn event_once +is similiar to +.Fn event_set . +However, it schedules a callback to be called exactly once and does not +require the caller to prepare an +.Fa event +structure. +This function supports +.Fa EV_TIMEOUT , +.Fa EV_READ +and +.Fa EV_WRITE . +.Pp +The +.Fn event_pending +function can be used to check if the event specified by +.Fa event +is pending to run. +If +.Va EV_TIMEOUT +was specified and +.Fa tv +is not +.Va NULL , +the expiration time of the event will be returned in +.Fa tv . +.Pp +The +.Fn event_initialized +macro can be used to check if an event has been initialized. +.Pp +The functions +.Fn evtimer_set , +.Fn evtimer_add , +.Fn evtimer_del , +.Fn evtimer_initialized , +and +.Fn evtimer_pending +are abbreviations for common situations where only a timeout is required. +The file descriptor passed will be 0, and the event type will be +.Va EV_TIMEOUT . +.Pp +.Pp +The functions +.Fn signal_set , +.Fn signal_add , +.Fn signal_del , +.Fn signal_initialized , +and +.Fn signal_pending +are abbreviations. +The event type will be a persistent +.Va EV_SIGNAL . +That means +.Fn signal_set +adds +.Va EV_PERSIST . +.Pp +It is possible to disable support for +.Va epoll , kqueue , poll +or +.Va select +by setting the environment variable +.Va EVENT_NOEPOLL , EVENT_NOKQUEUE , EVENT_NOPOLL +or +.Va EVENT_NOSELECT . +By setting the environment variable +.Va EVENT_SHOW_METHOD , +.Nm libevent +displays the kernel notification method that it uses. +.Pp +.Sh BUFFERED EVENTS +.Nm libevent +provides an abstraction on top of the regular event callbacks. +This abstraction is called a +.Va "buffered event" . +A buffered event provides input and output buffer that get filled +and drained automatically. +The user of a buffered event no longer deals directly with the IO, +but instead is reading from input and writing to output buffers. +.Pp +A new bufferevent is created by +.Fn bufferevent_new . +The parameter +.Fa "fd" +specifies the file descriptor from which data is read and written to. +This file descriptor is not allowed to be a +.Xr pipe 2 . +The next three parameters are callbacks. +The read and write callback have the following form +.Ft void +.Fn "(*cb)" "struct bufferevent *bufev" "void *arg" +The argument is specified by the fourth parameter +.Fa "cbarg" . +.Pp +By default the buffered event is read enabled and will try to read +from the file descriptor. +The write callback is executed whenever the output buffer is drained +below the write low watermark which is +.Va 0 +by default. +.Pp +The +.Fn bufferevent_write +function can be used to write data to the file descriptor. +The data is appended to the output buffer and written to the descriptor +automatically as it becomes available for writing. +The +.Fn bufferevent_read +function is used to read data from the input buffer. +Both functions return the amount of data written or read. +.Pp +.Sh RETURN VALUES +Upon successful completion +.Fn event_add +and +.Fn event_del +return 0. +Otherwise, -1 is returned and the global variable errno is +set to indicate the error. +.Sh SEE ALSO +.Xr timeout 9 , +.Xr select 2 , +.Xr kqueue 2 +.Sh HISTORY +The +.Nm event +API manpage is based on the +.Xr timeout 9 +manpage by Artur Grabowski. +The port of +.Nm libevent +to Windows is due to Michael A. Davis. +Support for real-time signals is due to Taral. +.Sh AUTHORS +The +.Nm event +library was written by Niels Provos. +.Pp +.Sh BUGS +This documentation is neither complete nor authorative. +If you are in doubt about the usage of this API then +check the source code to find out how it works, write +up the missing piece of documentation and send it to +me for inclusion in this man page. diff --git a/libevent/event.c b/libevent/event.c new file mode 100644 index 0000000..92eadde --- /dev/null +++ b/libevent/event.c @@ -0,0 +1,630 @@ +/* + * Copyright (c) 2000-2004 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include "misc.h" +#endif +#include +#include +#ifdef HAVE_SYS_TIME_H +#include +#else +#include +#endif +#include +#include +#include +#ifndef WIN32 +#include +#endif +#include +#include +#include +#include + +#ifdef USE_LOG +#include "log.h" +#else +#define LOG_DBG(x) +#define log_error(x) perror(x) +#endif + +#include "event.h" + +#ifdef HAVE_SELECT +extern const struct eventop selectops; +#endif +#ifdef HAVE_POLL +extern const struct eventop pollops; +#endif +#ifdef HAVE_RTSIG +extern const struct eventop rtsigops; +#endif +#ifdef HAVE_EPOLL +extern const struct eventop epollops; +#endif +#ifdef HAVE_WORKING_KQUEUE +extern const struct eventop kqops; +#endif +#ifdef WIN32 +extern const struct eventop win32ops; +#endif + +/* In order of preference */ +const struct eventop *eventops[] = { +#ifdef HAVE_WORKING_KQUEUE + &kqops, +#endif +#ifdef HAVE_EPOLL + &epollops, +#endif +#ifdef HAVE_RTSIG + &rtsigops, +#endif +#ifdef HAVE_POLL + &pollops, +#endif +#ifdef HAVE_SELECT + &selectops, +#endif +#ifdef WIN32 + &win32ops, +#endif + NULL +}; + +const struct eventop *evsel; +void *evbase; + +/* Handle signals - This is a deprecated interface */ +int (*event_sigcb)(void); /* Signal callback when gotsig is set */ +int event_gotsig; /* Set in signal handler */ +int event_gotterm; /* Set to terminate loop */ + +/* Prototypes */ +void event_queue_insert(struct event *, int); +void event_queue_remove(struct event *, int); +int event_haveevents(void); + +static void event_process_active(void); + +static RB_HEAD(event_tree, event) timetree; +static struct event_list activequeue; +struct event_list signalqueue; +struct event_list eventqueue; +static struct timeval event_tv; + +static int +compare(struct event *a, struct event *b) +{ + if (timercmp(&a->ev_timeout, &b->ev_timeout, <)) + return (-1); + else if (timercmp(&a->ev_timeout, &b->ev_timeout, >)) + return (1); + if (a < b) + return (-1); + if (a > b) + return (1); + return (0); +} + +RB_PROTOTYPE(event_tree, event, ev_timeout_node, compare); + +RB_GENERATE(event_tree, event, ev_timeout_node, compare); + + +void +event_init(void) +{ + int i; + + event_sigcb = NULL; + event_gotsig = 0; + gettimeofday(&event_tv, NULL); + + RB_INIT(&timetree); + TAILQ_INIT(&eventqueue); + TAILQ_INIT(&activequeue); + TAILQ_INIT(&signalqueue); + + evbase = NULL; + for (i = 0; eventops[i] && !evbase; i++) { + evsel = eventops[i]; + + evbase = evsel->init(); + } + + if (evbase == NULL) + errx(1, "%s: no event mechanism available", __func__); + + if (getenv("EVENT_SHOW_METHOD")) + fprintf(stderr, "libevent using: %s\n", evsel->name); + +#if defined(USE_LOG) && defined(USE_DEBUG) + log_to(stderr); + log_debug_cmd(LOG_MISC, 80); +#endif +} + +int +event_haveevents(void) +{ + return (RB_ROOT(&timetree) || TAILQ_FIRST(&eventqueue) || + TAILQ_FIRST(&signalqueue) || TAILQ_FIRST(&activequeue)); +} + +static void +event_process_active(void) +{ + struct event *ev; + short ncalls; + + for (ev = TAILQ_FIRST(&activequeue); ev; + ev = TAILQ_FIRST(&activequeue)) { + event_queue_remove(ev, EVLIST_ACTIVE); + + /* Allows deletes to work */ + ncalls = ev->ev_ncalls; + ev->ev_pncalls = &ncalls; + while (ncalls) { + ncalls--; + ev->ev_ncalls = ncalls; + (*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg); + } + } +} + +/* + * Wait continously for events. We exit only if no events are left. + */ + +int +event_dispatch(void) +{ + return (event_loop(0)); +} + +static void +event_loopexit_cb(int fd, short what, void *arg) +{ + event_gotterm = 1; +} + +int +event_loopexit(struct timeval *tv) +{ + return (event_once(-1, EV_TIMEOUT, event_loopexit_cb, NULL, tv)); +} + +int +event_loop(int flags) +{ + struct timeval tv; + int res, done; + + /* Calculate the initial events that we are waiting for */ + if (evsel->recalc(evbase, 0) == -1) + return (-1); + + done = 0; + while (!done) { + /* Terminate the loop if we have been asked to */ + if (event_gotterm) { + event_gotterm = 0; + break; + } + + while (event_gotsig) { + event_gotsig = 0; + if (event_sigcb) { + res = (*event_sigcb)(); + if (res == -1) { + errno = EINTR; + return (-1); + } + } + } + + /* Check if time is running backwards */ + gettimeofday(&tv, NULL); + if (timercmp(&tv, &event_tv, <)) { + struct timeval off; + LOG_DBG((LOG_MISC, 10, + "%s: time is running backwards, corrected", + __func__)); + + timersub(&event_tv, &tv, &off); + timeout_correct(&off); + } + event_tv = tv; + + if (!(flags & EVLOOP_NONBLOCK)) + timeout_next(&tv); + else + timerclear(&tv); + + /* If we have no events, we just exit */ + if (!event_haveevents()) + return (1); + + res = evsel->dispatch(evbase, &tv); + + if (res == -1) + return (-1); + + timeout_process(); + + if (TAILQ_FIRST(&activequeue)) { + event_process_active(); + if (flags & EVLOOP_ONCE) + done = 1; + } else if (flags & EVLOOP_NONBLOCK) + done = 1; + + if (evsel->recalc(evbase, 0) == -1) + return (-1); + } + + return (0); +} + +/* Sets up an event for processing once */ + +struct event_once { + struct event ev; + + void (*cb)(int, short, void *); + void *arg; +}; + +/* One-time callback, it deletes itself */ + +static void +event_once_cb(int fd, short events, void *arg) +{ + struct event_once *eonce = arg; + + (*eonce->cb)(fd, events, eonce->arg); + free(eonce); +} + +/* Schedules an event once */ + +int +event_once(int fd, short events, + void (*callback)(int, short, void *), void *arg, struct timeval *tv) +{ + struct event_once *eonce; + struct timeval etv; + + /* We cannot support signals that just fire once */ + if (events & EV_SIGNAL) + return (-1); + + if ((eonce = calloc(1, sizeof(struct event_once))) == NULL) + return (-1); + + if (events == EV_TIMEOUT) { + if (tv == NULL) { + timerclear(&etv); + tv = &etv; + } + + eonce->cb = callback; + eonce->arg = arg; + + evtimer_set(&eonce->ev, event_once_cb, eonce); + } else if (events & (EV_READ|EV_WRITE)) { + events &= EV_READ|EV_WRITE; + + event_set(&eonce->ev, fd, events, event_once_cb, eonce); + } else { + /* Bad event combination */ + return (-1); + } + + event_add(&eonce->ev, tv); + + return (0); +} + +void +event_set(struct event *ev, int fd, short events, + void (*callback)(int, short, void *), void *arg) +{ + ev->ev_callback = callback; + ev->ev_arg = arg; +#ifdef WIN32 + ev->ev_fd = (HANDLE)fd; + ev->overlap.hEvent = ev; +#else + ev->ev_fd = fd; +#endif + ev->ev_events = events; + ev->ev_flags = EVLIST_INIT; + ev->ev_ncalls = 0; + ev->ev_pncalls = NULL; +} + +/* + * Checks if a specific event is pending or scheduled. + */ + +int +event_pending(struct event *ev, short event, struct timeval *tv) +{ + int flags = 0; + + if (ev->ev_flags & EVLIST_INSERTED) + flags |= (ev->ev_events & (EV_READ|EV_WRITE)); + if (ev->ev_flags & EVLIST_ACTIVE) + flags |= ev->ev_res; + if (ev->ev_flags & EVLIST_TIMEOUT) + flags |= EV_TIMEOUT; + if (ev->ev_flags & EVLIST_SIGNAL) + flags |= EV_SIGNAL; + + event &= (EV_TIMEOUT|EV_READ|EV_WRITE|EV_SIGNAL); + + /* See if there is a timeout that we should report */ + if (tv != NULL && (flags & event & EV_TIMEOUT)) + *tv = ev->ev_timeout; + + return (flags & event); +} + +int +event_add(struct event *ev, struct timeval *tv) +{ + LOG_DBG((LOG_MISC, 55, + "event_add: event: %p, %s%s%scall %p", + ev, + ev->ev_events & EV_READ ? "EV_READ " : " ", + ev->ev_events & EV_WRITE ? "EV_WRITE " : " ", + tv ? "EV_TIMEOUT " : " ", + ev->ev_callback)); + + assert(!(ev->ev_flags & ~EVLIST_ALL)); + + if (tv != NULL) { + struct timeval now; + + if (ev->ev_flags & EVLIST_TIMEOUT) + event_queue_remove(ev, EVLIST_TIMEOUT); + + /* Check if it is active due to a timeout. Rescheduling + * this timeout before the callback can be executed + * removes it from the active list. */ + if ((ev->ev_flags & EVLIST_ACTIVE) && + (ev->ev_res & EV_TIMEOUT)) { + /* See if we are just active executing this + * event in a loop + */ + if (ev->ev_ncalls && ev->ev_pncalls) { + /* Abort loop */ + *ev->ev_pncalls = 0; + } + + event_queue_remove(ev, EVLIST_ACTIVE); + } + + gettimeofday(&now, NULL); + timeradd(&now, tv, &ev->ev_timeout); + + LOG_DBG((LOG_MISC, 55, + "event_add: timeout in %d seconds, call %p", + tv->tv_sec, ev->ev_callback)); + + event_queue_insert(ev, EVLIST_TIMEOUT); + } + + if ((ev->ev_events & (EV_READ|EV_WRITE)) && + !(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) { + event_queue_insert(ev, EVLIST_INSERTED); + + return (evsel->add(evbase, ev)); + } else if ((ev->ev_events & EV_SIGNAL) && + !(ev->ev_flags & EVLIST_SIGNAL)) { + event_queue_insert(ev, EVLIST_SIGNAL); + + return (evsel->add(evbase, ev)); + } + + return (0); +} + +int +event_del(struct event *ev) +{ + LOG_DBG((LOG_MISC, 80, "event_del: %p, callback %p", + ev, ev->ev_callback)); + + assert(!(ev->ev_flags & ~EVLIST_ALL)); + + /* See if we are just active executing this event in a loop */ + if (ev->ev_ncalls && ev->ev_pncalls) { + /* Abort loop */ + *ev->ev_pncalls = 0; + } + + if (ev->ev_flags & EVLIST_TIMEOUT) + event_queue_remove(ev, EVLIST_TIMEOUT); + + if (ev->ev_flags & EVLIST_ACTIVE) + event_queue_remove(ev, EVLIST_ACTIVE); + + if (ev->ev_flags & EVLIST_INSERTED) { + event_queue_remove(ev, EVLIST_INSERTED); + return (evsel->del(evbase, ev)); + } else if (ev->ev_flags & EVLIST_SIGNAL) { + event_queue_remove(ev, EVLIST_SIGNAL); + return (evsel->del(evbase, ev)); + } + + return (0); +} + +void +event_active(struct event *ev, int res, short ncalls) +{ + /* We get different kinds of events, add them together */ + if (ev->ev_flags & EVLIST_ACTIVE) { + ev->ev_res |= res; + return; + } + + ev->ev_res = res; + ev->ev_ncalls = ncalls; + ev->ev_pncalls = NULL; + event_queue_insert(ev, EVLIST_ACTIVE); +} + +int +timeout_next(struct timeval *tv) +{ + struct timeval dflt = TIMEOUT_DEFAULT; + + struct timeval now; + struct event *ev; + + if ((ev = RB_MIN(event_tree, &timetree)) == NULL) { + *tv = dflt; + return (0); + } + + if (gettimeofday(&now, NULL) == -1) + return (-1); + + if (timercmp(&ev->ev_timeout, &now, <=)) { + timerclear(tv); + return (0); + } + + timersub(&ev->ev_timeout, &now, tv); + + assert(tv->tv_sec >= 0); + assert(tv->tv_usec >= 0); + + LOG_DBG((LOG_MISC, 60, "timeout_next: in %d seconds", tv->tv_sec)); + return (0); +} + +void +timeout_correct(struct timeval *off) +{ + struct event *ev; + + /* We can modify the key element of the node without destroying + * the key, beause we apply it to all in the right order. + */ + RB_FOREACH(ev, event_tree, &timetree) + timersub(&ev->ev_timeout, off, &ev->ev_timeout); +} + +void +timeout_process(void) +{ + struct timeval now; + struct event *ev, *next; + + gettimeofday(&now, NULL); + + for (ev = RB_MIN(event_tree, &timetree); ev; ev = next) { + if (timercmp(&ev->ev_timeout, &now, >)) + break; + next = RB_NEXT(event_tree, &timetree, ev); + + event_queue_remove(ev, EVLIST_TIMEOUT); + + /* delete this event from the I/O queues */ + event_del(ev); + + LOG_DBG((LOG_MISC, 60, "timeout_process: call %p", + ev->ev_callback)); + event_active(ev, EV_TIMEOUT, 1); + } +} + +void +event_queue_remove(struct event *ev, int queue) +{ + if (!(ev->ev_flags & queue)) + errx(1, "%s: %p(fd %d) not on queue %x", __func__, + ev, ev->ev_fd, queue); + + ev->ev_flags &= ~queue; + switch (queue) { + case EVLIST_ACTIVE: + TAILQ_REMOVE(&activequeue, ev, ev_active_next); + break; + case EVLIST_SIGNAL: + TAILQ_REMOVE(&signalqueue, ev, ev_signal_next); + break; + case EVLIST_TIMEOUT: + RB_REMOVE(event_tree, &timetree, ev); + break; + case EVLIST_INSERTED: + TAILQ_REMOVE(&eventqueue, ev, ev_next); + break; + default: + errx(1, "%s: unknown queue %x", __func__, queue); + } +} + +void +event_queue_insert(struct event *ev, int queue) +{ + if (ev->ev_flags & queue) + errx(1, "%s: %p(fd %d) already on queue %x", __func__, + ev, ev->ev_fd, queue); + + ev->ev_flags |= queue; + switch (queue) { + case EVLIST_ACTIVE: + TAILQ_INSERT_TAIL(&activequeue, ev, ev_active_next); + break; + case EVLIST_SIGNAL: + TAILQ_INSERT_TAIL(&signalqueue, ev, ev_signal_next); + break; + case EVLIST_TIMEOUT: { + struct event *tmp = RB_INSERT(event_tree, &timetree, ev); + assert(tmp == NULL); + break; + } + case EVLIST_INSERTED: + TAILQ_INSERT_TAIL(&eventqueue, ev, ev_next); + break; + default: + errx(1, "%s: unknown queue %x", __func__, queue); + } +} diff --git a/libevent/event.h b/libevent/event.h new file mode 100644 index 0000000..eddb0e9 --- /dev/null +++ b/libevent/event.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2000-2004 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#ifndef _EVENT_H_ +#define _EVENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WIN32 +#include +#endif + +#define EVLIST_TIMEOUT 0x01 +#define EVLIST_INSERTED 0x02 +#define EVLIST_SIGNAL 0x04 +#define EVLIST_ACTIVE 0x08 +#define EVLIST_INIT 0x80 + +/* EVLIST_X_ Private space: 0x1000-0xf000 */ +#define EVLIST_ALL (0xf000 | 0x8f) + +#define EV_TIMEOUT 0x01 +#define EV_READ 0x02 +#define EV_WRITE 0x04 +#define EV_SIGNAL 0x08 +#define EV_PERSIST 0x10 /* Persistant event */ + +/* Fix so that ppl dont have to run with */ +#ifndef TAILQ_ENTRY +#define _EVENT_DEFINED_TQENTRY +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} +#endif /* !TAILQ_ENTRY */ +#ifndef RB_ENTRY +#define _EVENT_DEFINED_RBENTRY +#define RB_ENTRY(type) \ +struct { \ + struct type *rbe_left; /* left element */ \ + struct type *rbe_right; /* right element */ \ + struct type *rbe_parent; /* parent element */ \ + int rbe_color; /* node color */ \ +} +#endif /* !RB_ENTRY */ + +struct event { + TAILQ_ENTRY (event) ev_next; + TAILQ_ENTRY (event) ev_active_next; + TAILQ_ENTRY (event) ev_signal_next; + RB_ENTRY (event) ev_timeout_node; + +#ifdef WIN32 + HANDLE ev_fd; + OVERLAPPED overlap; +#else + int ev_fd; +#endif + short ev_events; + short ev_ncalls; + short *ev_pncalls; /* Allows deletes in callback */ + + struct timeval ev_timeout; + + void (*ev_callback)(int, short, void *arg); + void *ev_arg; + + int ev_res; /* result passed to event callback */ + int ev_flags; +}; + +#define EVENT_SIGNAL(ev) (int)ev->ev_fd +#define EVENT_FD(ev) (int)ev->ev_fd + +#ifdef _EVENT_DEFINED_TQENTRY +#undef TAILQ_ENTRY +#undef _EVENT_DEFINED_TQENTRY +#else +TAILQ_HEAD (event_list, event); +#endif /* _EVENT_DEFINED_TQENTRY */ +#ifdef _EVENT_DEFINED_RBENTRY +#undef RB_ENTRY +#undef _EVENT_DEFINED_RBENTRY +#endif /* _EVENT_DEFINED_RBENTRY */ + +struct eventop { + char *name; + void *(*init)(void); + int (*add)(void *, struct event *); + int (*del)(void *, struct event *); + int (*recalc)(void *, int); + int (*dispatch)(void *, struct timeval *); +}; + +#define TIMEOUT_DEFAULT {5, 0} + +void event_init(void); +int event_dispatch(void); + +#define EVLOOP_ONCE 0x01 +#define EVLOOP_NONBLOCK 0x02 +int event_loop(int); +int event_loopexit(struct timeval *); /* Causes the loop to exit */ + +int timeout_next(struct timeval *); +void timeout_correct(struct timeval *); +void timeout_process(void); + +#define evtimer_add(ev, tv) event_add(ev, tv) +#define evtimer_set(ev, cb, arg) event_set(ev, -1, 0, cb, arg) +#define evtimer_del(ev) event_del(ev) +#define evtimer_pending(ev, tv) event_pending(ev, EV_TIMEOUT, tv) +#define evtimer_initialized(ev) ((ev)->ev_flags & EVLIST_INIT) + +#define timeout_add(ev, tv) event_add(ev, tv) +#define timeout_set(ev, cb, arg) event_set(ev, -1, 0, cb, arg) +#define timeout_del(ev) event_del(ev) +#define timeout_pending(ev, tv) event_pending(ev, EV_TIMEOUT, tv) +#define timeout_initialized(ev) ((ev)->ev_flags & EVLIST_INIT) + +#define signal_add(ev, tv) event_add(ev, tv) +#define signal_set(ev, x, cb, arg) \ + event_set(ev, x, EV_SIGNAL|EV_PERSIST, cb, arg) +#define signal_del(ev) event_del(ev) +#define signal_pending(ev, tv) event_pending(ev, EV_SIGNAL, tv) +#define signal_initialized(ev) ((ev)->ev_flags & EVLIST_INIT) + +void event_set(struct event *, int, short, void (*)(int, short, void *), void *); +int event_once(int, short, void (*)(int, short, void *), void *, struct timeval *); + +int event_add(struct event *, struct timeval *); +int event_del(struct event *); +void event_active(struct event *, int, short); + +int event_pending(struct event *, short, struct timeval *); + +#ifdef WIN32 +#define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT && (ev)->ev_fd != INVALID_HANDLE_VALUE) +#else +#define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT) +#endif + +/* These functions deal with buffering input and output */ + +struct evbuffer { + u_char *buffer; + + size_t totallen; + size_t off; + + void (*cb)(struct evbuffer *, size_t, size_t, void *); + void *cbarg; +}; + +/* Just for error reporting - use other constants otherwise */ +#define EVBUFFER_READ 0x01 +#define EVBUFFER_WRITE 0x02 +#define EVBUFFER_EOF 0x10 +#define EVBUFFER_ERROR 0x20 +#define EVBUFFER_TIMEOUT 0x40 + +struct bufferevent; +typedef void (*evbuffercb)(struct bufferevent *, void *); +typedef void (*everrorcb)(struct bufferevent *, short what, void *); + +struct event_watermark { + size_t low; + size_t high; +}; + +struct bufferevent { + struct event ev_read; + struct event ev_write; + + struct evbuffer *input; + struct evbuffer *output; + + struct event_watermark wm_read; + struct event_watermark wm_write; + + evbuffercb readcb; + evbuffercb writecb; + everrorcb errorcb; + void *cbarg; + + int timeout_read; /* in seconds */ + int timeout_write; /* in seconds */ + + short enabled; /* events that are currently enabled */ +}; + +struct bufferevent *bufferevent_new(int fd, + evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg); +void bufferevent_free(struct bufferevent *bufev); +int bufferevent_write(struct bufferevent *bufev, void *data, size_t size); +int bufferevent_write_buffer(struct bufferevent *bufev, struct evbuffer *buf); +size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size); +int bufferevent_enable(struct bufferevent *bufev, short event); +int bufferevent_disable(struct bufferevent *bufev, short event); +void bufferevent_settimeout(struct bufferevent *bufev, + int timeout_read, int timeout_write); + +#define EVBUFFER_LENGTH(x) (x)->off +#define EVBUFFER_DATA(x) (x)->buffer +#define EVBUFFER_INPUT(x) (x)->input +#define EVBUFFER_OUTPUT(x) (x)->output + +struct evbuffer *evbuffer_new(void); +void evbuffer_free(struct evbuffer *); +int evbuffer_add(struct evbuffer *, u_char *, size_t); +int evbuffer_add_buffer(struct evbuffer *, struct evbuffer *); +int evbuffer_add_printf(struct evbuffer *, char *fmt, ...); +void evbuffer_drain(struct evbuffer *, size_t); +int evbuffer_write(struct evbuffer *, int); +int evbuffer_read(struct evbuffer *, int, int); +u_char *evbuffer_find(struct evbuffer *, u_char *, size_t); +void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_t, void *), void *); + +#ifdef __cplusplus +} +#endif + +#endif /* _EVENT_H_ */ diff --git a/libevent/evsignal.h b/libevent/evsignal.h new file mode 100644 index 0000000..8de27a5 --- /dev/null +++ b/libevent/evsignal.h @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2002 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#ifndef _EVSIGNAL_H_ +#define _EVSIGNAL_H_ + +void evsignal_init(sigset_t *); +void evsignal_process(void); +int evsignal_recalc(sigset_t *); +int evsignal_deliver(sigset_t *); +int evsignal_add(sigset_t *, struct event *); +int evsignal_del(sigset_t *, struct event *); + +#endif /* _EVSIGNAL_H_ */ diff --git a/libevent/install-sh b/libevent/install-sh new file mode 100755 index 0000000..89fc9b0 --- /dev/null +++ b/libevent/install-sh @@ -0,0 +1,238 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# 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. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +tranformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# 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 $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/libevent/kqueue.c b/libevent/kqueue.c new file mode 100644 index 0000000..49bbced --- /dev/null +++ b/libevent/kqueue.c @@ -0,0 +1,378 @@ +/* $OpenBSD: kqueue.c,v 1.5 2002/07/10 14:41:31 art Exp $ */ + +/* + * Copyright 2000-2002 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#ifdef HAVE_SYS_TIME_H +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_INTTYPES_H +#include +#endif + +#ifdef USE_LOG +#include "log.h" +#else +#define LOG_DBG(x) +#define log_error warn +#endif + +#if defined(HAVE_INTTYPES_H) && !defined(__OpenBSD__) +#define INTPTR(x) (intptr_t)x +#else +#define INTPTR(x) x +#endif + +#include "event.h" + +extern struct event_list timequeue; +extern struct event_list eventqueue; +extern struct event_list addqueue; + +#define EVLIST_X_KQINKERNEL 0x1000 + +#define NEVENT 64 + +struct kqop { + struct kevent *changes; + int nchanges; + struct kevent *events; + int nevents; + int kq; +} kqueueop; + +void *kq_init (void); +int kq_add (void *, struct event *); +int kq_del (void *, struct event *); +int kq_recalc (void *, int); +int kq_dispatch (void *, struct timeval *); +int kq_insert (struct kqop *, struct kevent *); + +const struct eventop kqops = { + "kqueue", + kq_init, + kq_add, + kq_del, + kq_recalc, + kq_dispatch +}; + +void * +kq_init(void) +{ + int kq; + + /* Disable kqueue when this environment variable is set */ + if (getenv("EVENT_NOKQUEUE")) + return (NULL); + + memset(&kqueueop, 0, sizeof(kqueueop)); + + /* Initalize the kernel queue */ + + if ((kq = kqueue()) == -1) { + log_error("kqueue"); + return (NULL); + } + + kqueueop.kq = kq; + + /* Initalize fields */ + kqueueop.changes = malloc(NEVENT * sizeof(struct kevent)); + if (kqueueop.changes == NULL) + return (NULL); + kqueueop.events = malloc(NEVENT * sizeof(struct kevent)); + if (kqueueop.events == NULL) { + free (kqueueop.changes); + return (NULL); + } + kqueueop.nevents = NEVENT; + + return (&kqueueop); +} + +int +kq_recalc(void *arg, int max) +{ + return (0); +} + +int +kq_insert(struct kqop *kqop, struct kevent *kev) +{ + int nevents = kqop->nevents; + + if (kqop->nchanges == nevents) { + struct kevent *newchange; + struct kevent *newresult; + + nevents *= 2; + + newchange = realloc(kqop->changes, + nevents * sizeof(struct kevent)); + if (newchange == NULL) { + log_error("%s: malloc", __func__); + return (-1); + } + kqop->changes = newchange; + + newresult = realloc(kqop->events, + nevents * sizeof(struct kevent)); + + /* + * If we fail, we don't have to worry about freeing, + * the next realloc will pick it up. + */ + if (newresult == NULL) { + log_error("%s: malloc", __func__); + return (-1); + } + kqop->events = newresult; + + kqop->nevents = nevents; + } + + memcpy(&kqop->changes[kqop->nchanges++], kev, sizeof(struct kevent)); + + LOG_DBG((LOG_MISC, 70, "%s: fd %d %s%s", + __func__, kev->ident, + kev->filter == EVFILT_READ ? "EVFILT_READ" : "EVFILT_WRITE", + kev->flags == EV_DELETE ? " (del)" : "")); + + return (0); +} + +static void +kq_sighandler(int sig) +{ + /* Do nothing here */ +} + +int +kq_dispatch(void *arg, struct timeval *tv) +{ + struct kqop *kqop = arg; + struct kevent *changes = kqop->changes; + struct kevent *events = kqop->events; + struct event *ev; + struct timespec ts; + int i, res; + + TIMEVAL_TO_TIMESPEC(tv, &ts); + + res = kevent(kqop->kq, changes, kqop->nchanges, + events, kqop->nevents, &ts); + kqop->nchanges = 0; + if (res == -1) { + if (errno != EINTR) { + log_error("kevent"); + return (-1); + } + + return (0); + } + + LOG_DBG((LOG_MISC, 80, "%s: kevent reports %d", __func__, res)); + + for (i = 0; i < res; i++) { + int which = 0; + + if (events[i].flags & EV_ERROR) { + /* + * Error messages that can happen, when a delete fails. + * EBADF happens when the file discriptor has been + * closed, + * ENOENT when the file discriptor was closed and + * then reopened. + * An error is also indicated when a callback deletes + * an event we are still processing. In that case + * the data field is set to ENOENT. + */ + if (events[i].data == EBADF || + events[i].data == ENOENT) + continue; + return (-1); + } + + ev = (struct event *)events[i].udata; + + if (events[i].filter == EVFILT_READ) { + which |= EV_READ; + } else if (events[i].filter == EVFILT_WRITE) { + which |= EV_WRITE; + } else if (events[i].filter == EVFILT_SIGNAL) { + which |= EV_SIGNAL; + } + + if (!which) + continue; + + if (!(ev->ev_events & EV_PERSIST)) { + ev->ev_flags &= ~EVLIST_X_KQINKERNEL; + event_del(ev); + } + + event_active(ev, which, + ev->ev_events & EV_SIGNAL ? events[i].data : 1); + } + + return (0); +} + + +int +kq_add(void *arg, struct event *ev) +{ + struct kqop *kqop = arg; + struct kevent kev; + + if (ev->ev_events & EV_SIGNAL) { + int nsignal = EVENT_SIGNAL(ev); + + memset(&kev, 0, sizeof(kev)); + kev.ident = nsignal; + kev.filter = EVFILT_SIGNAL; + kev.flags = EV_ADD; + if (!(ev->ev_events & EV_PERSIST)) + kev.flags |= EV_ONESHOT; + kev.udata = INTPTR(ev); + + if (kq_insert(kqop, &kev) == -1) + return (-1); + + if (signal(nsignal, kq_sighandler) == SIG_ERR) + return (-1); + + ev->ev_flags |= EVLIST_X_KQINKERNEL; + return (0); + } + + if (ev->ev_events & EV_READ) { + memset(&kev, 0, sizeof(kev)); + kev.ident = ev->ev_fd; + kev.filter = EVFILT_READ; +#ifdef NOTE_EOF + /* Make it behave like select() and poll() */ + kev.fflags = NOTE_EOF; +#endif + kev.flags = EV_ADD; + if (!(ev->ev_events & EV_PERSIST)) + kev.flags |= EV_ONESHOT; + kev.udata = INTPTR(ev); + + if (kq_insert(kqop, &kev) == -1) + return (-1); + + ev->ev_flags |= EVLIST_X_KQINKERNEL; + } + + if (ev->ev_events & EV_WRITE) { + memset(&kev, 0, sizeof(kev)); + kev.ident = ev->ev_fd; + kev.filter = EVFILT_WRITE; + kev.flags = EV_ADD; + if (!(ev->ev_events & EV_PERSIST)) + kev.flags |= EV_ONESHOT; + kev.udata = INTPTR(ev); + + if (kq_insert(kqop, &kev) == -1) + return (-1); + + ev->ev_flags |= EVLIST_X_KQINKERNEL; + } + + return (0); +} + +int +kq_del(void *arg, struct event *ev) +{ + struct kqop *kqop = arg; + struct kevent kev; + + if (!(ev->ev_flags & EVLIST_X_KQINKERNEL)) + return (0); + + if (ev->ev_events & EV_SIGNAL) { + int nsignal = EVENT_SIGNAL(ev); + + memset(&kev, 0, sizeof(kev)); + kev.ident = (int)signal; + kev.filter = EVFILT_SIGNAL; + kev.flags = EV_DELETE; + + if (kq_insert(kqop, &kev) == -1) + return (-1); + + if (signal(nsignal, SIG_DFL) == SIG_ERR) + return (-1); + + ev->ev_flags &= ~EVLIST_X_KQINKERNEL; + return (0); + } + + if (ev->ev_events & EV_READ) { + memset(&kev, 0, sizeof(kev)); + kev.ident = ev->ev_fd; + kev.filter = EVFILT_READ; + kev.flags = EV_DELETE; + + if (kq_insert(kqop, &kev) == -1) + return (-1); + + ev->ev_flags &= ~EVLIST_X_KQINKERNEL; + } + + if (ev->ev_events & EV_WRITE) { + memset(&kev, 0, sizeof(kev)); + kev.ident = ev->ev_fd; + kev.filter = EVFILT_WRITE; + kev.flags = EV_DELETE; + + if (kq_insert(kqop, &kev) == -1) + return (-1); + + ev->ev_flags &= ~EVLIST_X_KQINKERNEL; + } + + return (0); +} diff --git a/libevent/missing b/libevent/missing new file mode 100755 index 0000000..d46f79f --- /dev/null +++ b/libevent/missing @@ -0,0 +1,198 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc. +# Franc,ois Pinard , 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.in; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`$configure_ac'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`$configure_ac'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`$configure_ac'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/libevent/mkinstalldirs b/libevent/mkinstalldirs new file mode 100755 index 0000000..6b3b5fc --- /dev/null +++ b/libevent/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/libevent/poll.c b/libevent/poll.c new file mode 100644 index 0000000..773e4d1 --- /dev/null +++ b/libevent/poll.c @@ -0,0 +1,245 @@ +/* $OpenBSD: poll.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */ + +/* + * Copyright 2000-2003 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#ifdef HAVE_SYS_TIME_H +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_LOG +#include "log.h" +#else +#define LOG_DBG(x) +#define log_error(x) perror(x) +#endif + +#include "event.h" +#include "evsignal.h" + +extern struct event_list eventqueue; + +extern volatile sig_atomic_t evsignal_caught; + +struct pollop { + int event_count; /* Highest number alloc */ + struct pollfd *event_set; + struct event **event_back; + sigset_t evsigmask; +} pollop; + +void *poll_init (void); +int poll_add (void *, struct event *); +int poll_del (void *, struct event *); +int poll_recalc (void *, int); +int poll_dispatch (void *, struct timeval *); + +struct eventop pollops = { + "poll", + poll_init, + poll_add, + poll_del, + poll_recalc, + poll_dispatch +}; + +void * +poll_init(void) +{ + /* Disable kqueue when this environment variable is set */ + if (getenv("EVENT_NOPOLL")) + return (NULL); + + memset(&pollop, 0, sizeof(pollop)); + + evsignal_init(&pollop.evsigmask); + + return (&pollop); +} + +/* + * Called with the highest fd that we know about. If it is 0, completely + * recalculate everything. + */ + +int +poll_recalc(void *arg, int max) +{ + struct pollop *pop = arg; + + return (evsignal_recalc(&pop->evsigmask)); +} + +int +poll_dispatch(void *arg, struct timeval *tv) +{ + int res, i, count, sec, nfds; + struct event *ev; + struct pollop *pop = arg; + + count = pop->event_count; + nfds = 0; + TAILQ_FOREACH(ev, &eventqueue, ev_next) { + if (nfds + 1 >= count) { + if (count < 32) + count = 32; + else + count *= 2; + + /* We need more file descriptors */ + pop->event_set = realloc(pop->event_set, + count * sizeof(struct pollfd)); + if (pop->event_set == NULL) { + log_error("realloc"); + return (-1); + } + pop->event_back = realloc(pop->event_back, + count * sizeof(struct event *)); + if (pop->event_back == NULL) { + log_error("realloc"); + return (-1); + } + pop->event_count = count; + } + if (ev->ev_events & EV_WRITE) { + struct pollfd *pfd = &pop->event_set[nfds]; + pfd->fd = ev->ev_fd; + pfd->events = POLLOUT; + pfd->revents = 0; + + pop->event_back[nfds] = ev; + + nfds++; + } + if (ev->ev_events & EV_READ) { + struct pollfd *pfd = &pop->event_set[nfds]; + + pfd->fd = ev->ev_fd; + pfd->events = POLLIN; + pfd->revents = 0; + + pop->event_back[nfds] = ev; + + nfds++; + } + } + + if (evsignal_deliver(&pop->evsigmask) == -1) + return (-1); + + sec = tv->tv_sec * 1000 + tv->tv_usec / 1000; + res = poll(pop->event_set, nfds, sec); + + if (evsignal_recalc(&pop->evsigmask) == -1) + return (-1); + + if (res == -1) { + if (errno != EINTR) { + log_error("poll"); + return (-1); + } + + evsignal_process(); + return (0); + } else if (evsignal_caught) + evsignal_process(); + + LOG_DBG((LOG_MISC, 80, "%s: poll reports %d", __func__, res)); + + if (res == 0) + return (0); + + for (i = 0; i < nfds; i++) { + int what = pop->event_set[i].revents; + + res = 0; + + /* If the file gets closed notify */ + if (what & POLLHUP) + what |= POLLIN|POLLOUT; + if (what & POLLERR) + what |= POLLIN|POLLOUT; + if (what & POLLIN) + res |= EV_READ; + if (what & POLLOUT) + res |= EV_WRITE; + if (res == 0) + continue; + + ev = pop->event_back[i]; + res &= ev->ev_events; + + if (res) { + if (!(ev->ev_events & EV_PERSIST)) + event_del(ev); + event_active(ev, res, 1); + } + } + + return (0); +} + +int +poll_add(void *arg, struct event *ev) +{ + struct pollop *pop = arg; + + if (ev->ev_events & EV_SIGNAL) + return (evsignal_add(&pop->evsigmask, ev)); + + return (0); +} + +/* + * Nothing to be done here. + */ + +int +poll_del(void *arg, struct event *ev) +{ + struct pollop *pop = arg; + + if (!(ev->ev_events & EV_SIGNAL)) + return (0); + + return (evsignal_del(&pop->evsigmask, ev)); +} diff --git a/libevent/rtsig.c b/libevent/rtsig.c new file mode 100644 index 0000000..960715f --- /dev/null +++ b/libevent/rtsig.c @@ -0,0 +1,434 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Enable F_SETSIG and F_SETOWN */ +#define _GNU_SOURCE + +#include +#ifdef HAVE_SYS_TIME_H +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef HAVE_WORKING_RTSIG +#include +#endif +#include + +#define EVLIST_X_NORT 0x1000 /* Skip RT signals (internal) */ + +#include "event.h" +extern struct event_list eventqueue; +extern struct event_list signalqueue; + +struct rtsigop { + sigset_t sigs; + struct pollfd *poll; + struct event **toev; + int cur, max, total; +#ifndef HAVE_WORKING_RTSIG + int pollmode; +#endif +}; + +#define INIT_MAX 16 + +static int +poll_add(struct rtsigop *op, struct event *ev) +{ + struct pollfd *pfd; + + if (op->poll == NULL) return 0; + + if (op->cur == op->max) { + void *p; + + p = realloc(op->poll, sizeof(*op->poll) * (op->max << 1)); + if (!p) { + errno = ENOMEM; + return -1; + } + op->poll = p; + p = realloc(op->toev, sizeof(*op->toev) * (op->max << 1)); + if (!p) { + op->poll = realloc(op->poll, sizeof(*op->poll) * op->max); + errno = ENOMEM; + return -1; + } + op->toev = p; + op->max <<= 1; + } + + pfd = &op->poll[op->cur]; + pfd->fd = ev->ev_fd; + pfd->events = 0; + if (ev->ev_events & EV_READ) pfd->events |= POLLIN; + if (ev->ev_events & EV_WRITE) pfd->events |= POLLOUT; + pfd->revents = 0; + + op->toev[op->cur] = ev; + op->cur++; + + return 0; +} + +static void +poll_free(struct rtsigop *op, int n) +{ + if (op->poll == NULL) return; + + op->cur--; + if (n < op->cur) { + memcpy(&op->poll[n], &op->poll[op->cur], sizeof(*op->poll)); + op->toev[n] = op->toev[op->cur]; + } + if (op->max > INIT_MAX && op->cur < op->max >> 1) { + op->max >>= 1; + op->poll = realloc(op->poll, sizeof(*op->poll) * op->max); + op->toev = realloc(op->toev, sizeof(*op->toev) * op->max); + } +} + +static void +poll_remove(struct rtsigop *op, struct event *ev) +{ + int i; + + for (i = 0; i < op->cur; i++) { + if (op->toev[i] == ev) { + poll_free(op, i); + break; + } + } +} + +static void +activate(struct event *ev, int flags) +{ + if (!(ev->ev_events & EV_PERSIST)) event_del(ev); + event_active(ev, flags, 1); +} + +void *rtsig_init(void); +int rtsig_add(void *, struct event *); +int rtsig_del(void *, struct event *); +int rtsig_recalc(void *, int); +int rtsig_dispatch(void *, struct timeval *); + +struct eventop rtsigops = { + "rtsig", + rtsig_init, + rtsig_add, + rtsig_del, + rtsig_recalc, + rtsig_dispatch +}; + +void * +rtsig_init(void) +{ + struct rtsigop *op; + + if (getenv("EVENT_NORTSIG")) + return (NULL); + + op = malloc(sizeof(*op)); + if (op == NULL) return (NULL); + + memset(op, 0, sizeof(*op)); + + op->max = INIT_MAX; + op->poll = malloc(sizeof(*op->poll) * op->max); + if (op->poll == NULL) { + free(op); + return (NULL); + } + op->toev = malloc(sizeof(*op->toev) * op->max); + if (op->toev == NULL) { + free(op->poll); + free(op); + return (NULL); + } + + sigemptyset(&op->sigs); + sigaddset(&op->sigs, SIGIO); + sigaddset(&op->sigs, SIGRTMIN); + sigprocmask(SIG_BLOCK, &op->sigs, NULL); + + return (op); +} + +int +rtsig_add(void *arg, struct event *ev) +{ + struct rtsigop *op = (struct rtsigop *) arg; + int flags, i; +#ifndef HAVE_WORKING_RTSIG + struct stat st; +#endif + + if (ev->ev_events & EV_SIGNAL) { + sigaddset(&op->sigs, EVENT_SIGNAL(ev)); + return sigprocmask(SIG_BLOCK, &op->sigs, NULL); + } + + if (!(ev->ev_events & (EV_READ | EV_WRITE))) return 0; + +#ifndef HAVE_WORKING_RTSIG + if (fstat(ev->ev_fd, &st) == -1) return -1; + if (S_ISFIFO(st.st_mode)) { + ev->ev_flags |= EVLIST_X_NORT; + op->pollmode++; + } +#endif + + flags = fcntl(ev->ev_fd, F_GETFL); + if (flags == -1) + return (-1); + + if (!(flags & O_ASYNC)) { + if (fcntl(ev->ev_fd, F_SETSIG, SIGRTMIN) == -1 + || fcntl(ev->ev_fd, F_SETOWN, (int) getpid()) == -1) + return (-1); + + if (fcntl(ev->ev_fd, F_SETFL, flags | O_ASYNC)) + return (-1); + } + +#ifdef O_ONESIGFD + fcntl(ev->ev_fd, F_SETAUXFL, O_ONESIGFD); +#endif + + op->total++; + if (poll_add(op, ev) == -1) + goto err; + + return (0); + + err: + i = errno; + fcntl(ev->ev_fd, F_SETFL, flags); + errno = i; + return (-1); +} + +int +rtsig_del(void *arg, struct event *ev) +{ + struct rtsigop *op = (struct rtsigop *) arg; + + if (ev->ev_events & EV_SIGNAL) { + sigset_t sigs; + + sigdelset(&op->sigs, EVENT_SIGNAL(ev)); + + sigemptyset(&sigs); + sigaddset(&sigs, EVENT_SIGNAL(ev)); + return (sigprocmask(SIG_UNBLOCK, &sigs, NULL)); + } + + if (!(ev->ev_events & (EV_READ | EV_WRITE))) + return (0); + +#ifndef HAVE_WORKING_RTSIG + if (ev->ev_flags & EVLIST_X_NORT) + op->pollmode--; +#endif + poll_remove(op, ev); + op->total--; + + return (0); +} + +int +rtsig_recalc(void *arg, int max) +{ + return (0); +} + +int +rtsig_dispatch(void *arg, struct timeval *tv) +{ + struct rtsigop *op = (struct rtsigop *) arg; + struct timespec ts; + int res, i; + + if (op->poll == NULL) + goto retry_poll; +#ifndef HAVE_WORKING_RTSIG + if (op->pollmode) + goto poll_all; +#endif + + if (op->cur) { + ts.tv_sec = ts.tv_nsec = 0; + } else { + ts.tv_sec = tv->tv_sec; + ts.tv_nsec = tv->tv_usec * 1000; + } + + for (;;) { + siginfo_t info; + struct event *ev; + int signum; + + signum = sigtimedwait(&op->sigs, &info, &ts); + + if (signum == -1) { + if (errno == EAGAIN) + break; + return (errno == EINTR ? 0 : -1); + } + + ts.tv_sec = ts.tv_nsec = 0; + + if (signum == SIGIO) { +#ifndef HAVE_WORKING_RTSIG + poll_all: +#endif + free(op->poll); + free(op->toev); + retry_poll: + op->cur = 0; + op->max = op->total; + op->poll = malloc(sizeof(*op->poll) * op->total); + if (op->poll == NULL) + return (-1); + op->toev = malloc(sizeof(*op->toev) * op->total); + if (op->toev == NULL) { + free(op->poll); + op->poll = NULL; + return (-1); + } + + TAILQ_FOREACH(ev, &eventqueue, ev_next) + if (!(ev->ev_flags & EVLIST_X_NORT)) + poll_add(op, ev); + + break; + } + + if (signum == SIGRTMIN) { + int flags, i, sigok = 0; + + if (info.si_band <= 0) { /* SI_SIGIO */ + flags = EV_READ | EV_WRITE; + } else { + flags = 0; + if (info.si_band & POLLIN) flags |= EV_READ; + if (info.si_band & POLLOUT) flags |= EV_WRITE; + if (!flags) continue; + } + + for (i = 0; flags && i < op->cur; i++) { + ev = op->toev[i]; + + if (ev->ev_fd == info.si_fd) { + flags &= ~ev->ev_events; + sigok = 1; + } + } + + for (ev = TAILQ_FIRST(&eventqueue); + flags && ev != TAILQ_END(&eventqueue); + ev = TAILQ_NEXT(ev, ev_next)) { + if (ev->ev_fd == info.si_fd) { + if (flags & ev->ev_events) { + i = poll_add(op, ev); + if (i == -1) return -1; + flags &= ~ev->ev_events; + } + sigok = 1; + } + } + + if (!sigok) { + flags = fcntl(info.si_fd, F_GETFL); + if (flags == -1) return -1; + fcntl(info.si_fd, F_SETFL, flags & ~O_ASYNC); + } + } else { + TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) { + if (EVENT_SIGNAL(ev) == signum) + activate(ev, EV_SIGNAL); + } + } + } + + if (!op->cur) + return (0); + + res = poll(op->poll, op->cur, tv->tv_sec * 1000 + tv->tv_usec / 1000); + if (res < 0) + return (-1); + + i = 0; +#ifdef HAVE_WORKING_RTSIG + while (i < res) { +#else + while (i < op->cur) { +#endif + if (op->poll[i].revents) { + int flags = 0; + struct event *ev = op->toev[i]; + + if (op->poll[i].revents & POLLIN) + flags |= EV_READ; + if (op->poll[i].revents & POLLOUT) + flags |= EV_WRITE; + + if (!(ev->ev_events & EV_PERSIST)) { + event_del(ev); + res--; + } else { + i++; + } + event_active(ev, flags, 1); + } else { +#ifndef HAVE_WORKING_RTSIG + if (op->toev[i]->ev_flags & EVLIST_X_NORT) { + i++; + res++; + continue; + } +#endif + for (;;) { + op->cur--; + if (i == op->cur) + break; + if (op->poll[op->cur].revents) { + memcpy(&op->poll[i], &op->poll[op->cur], sizeof(*op->poll)); + op->toev[i] = op->toev[op->cur]; + break; + } + } + } + } +#ifdef HAVE_WORKING_RTSIG + op->cur = res; +#endif + + if (!op->cur) { + op->max = INIT_MAX; + free(op->poll); + free(op->toev); + /* We just freed it, we shouldn't have a problem getting it back. */ + op->poll = malloc(sizeof(*op->poll) * op->max); + op->toev = malloc(sizeof(*op->toev) * op->max); + + if (op->poll == NULL || op->toev == NULL) + err(1, "%s: malloc"); + } + + return (0); +} diff --git a/libevent/sample/Makefile.am b/libevent/sample/Makefile.am new file mode 100644 index 0000000..b2a0481 --- /dev/null +++ b/libevent/sample/Makefile.am @@ -0,0 +1,13 @@ +AUTOMAKE_OPTIONS = foreign no-dependencies + +LDADD = -L.. -levent +CPPFPLAGS = -I.. +CFLAGS = -I../compat + +noinst_PROGRAMS = event-test time-test signal-test + +event_test_sources = event-test.c +time_test_sources = time-test.c +signal_test_sources = signal-test.c + +DISTCLEANFILES = *~ diff --git a/libevent/sample/Makefile.in b/libevent/sample/Makefile.in new file mode 100644 index 0000000..3e938e4 --- /dev/null +++ b/libevent/sample/Makefile.in @@ -0,0 +1,287 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 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. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +CC = @CC@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ + +AUTOMAKE_OPTIONS = foreign no-dependencies + +LDADD = -L.. -levent +CPPFPLAGS = -I.. +CFLAGS = -I../compat + +noinst_PROGRAMS = event-test time-test signal-test + +event_test_sources = event-test.c +time_test_sources = time-test.c +signal_test_sources = signal-test.c + +DISTCLEANFILES = *~ +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(noinst_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +event_test_SOURCES = event-test.c +event_test_OBJECTS = event-test.o +event_test_LDADD = $(LDADD) +event_test_DEPENDENCIES = +event_test_LDFLAGS = +time_test_SOURCES = time-test.c +time_test_OBJECTS = time-test.o +time_test_LDADD = $(LDADD) +time_test_DEPENDENCIES = +time_test_LDFLAGS = +signal_test_SOURCES = signal-test.c +signal_test_OBJECTS = signal-test.o +signal_test_LDADD = $(LDADD) +signal_test_DEPENDENCIES = +signal_test_LDFLAGS = +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = event-test.c time-test.c signal-test.c +OBJECTS = event-test.o time-test.o signal-test.o + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign sample/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +event-test: $(event_test_OBJECTS) $(event_test_DEPENDENCIES) + @rm -f event-test + $(LINK) $(event_test_LDFLAGS) $(event_test_OBJECTS) $(event_test_LDADD) $(LIBS) + +time-test: $(time_test_OBJECTS) $(time_test_DEPENDENCIES) + @rm -f time-test + $(LINK) $(time_test_LDFLAGS) $(time_test_OBJECTS) $(time_test_LDADD) $(LIBS) + +signal-test: $(signal_test_OBJECTS) $(signal_test_DEPENDENCIES) + @rm -f signal-test + $(LINK) $(signal_test_LDFLAGS) $(signal_test_OBJECTS) $(signal_test_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = sample + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstPROGRAMS clean-compile clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstPROGRAMS distclean-compile distclean-tags \ + distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libevent/sample/event-test.c b/libevent/sample/event-test.c new file mode 100644 index 0000000..0eac37e --- /dev/null +++ b/libevent/sample/event-test.c @@ -0,0 +1,135 @@ +/* + * Compile with: + * cc -I/usr/local/include -o event-test event-test.c -L/usr/local/lib -levent + */ + +#include +#include +#ifndef WIN32 +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include + +#include + +void +fifo_read(int fd, short event, void *arg) +{ + char buf[255]; + int len; + struct event *ev = arg; +#ifdef WIN32 + DWORD dwBytesRead; +#endif + + /* Reschedule this event */ + event_add(ev, NULL); + + fprintf(stderr, "fifo_read called with fd: %d, event: %d, arg: %p\n", + fd, event, arg); +#ifdef WIN32 + len = ReadFile((HANDLE)fd, buf, sizeof(buf) - 1, &dwBytesRead, NULL); + + // Check for end of file. + if(len && dwBytesRead == 0) { + fprintf(stderr, "End Of File"); + event_del(ev); + return; + } + + buf[dwBytesRead + 1] = '\0'; +#else + len = read(fd, buf, sizeof(buf) - 1); + + if (len == -1) { + perror("read"); + return; + } else if (len == 0) { + fprintf(stderr, "Connection closed\n"); + return; + } + + buf[len] = '\0'; +#endif + fprintf(stdout, "Read: %s\n", buf); +} + +int +main (int argc, char **argv) +{ + struct event evfifo; +#ifdef WIN32 + HANDLE socket; + // Open a file. + socket = CreateFile("test.txt", // open File + GENERIC_READ, // open for reading + 0, // do not share + NULL, // no security + OPEN_EXISTING, // existing file only + FILE_ATTRIBUTE_NORMAL, // normal file + NULL); // no attr. template + + if(socket == INVALID_HANDLE_VALUE) + return 1; + +#else + struct stat st; + char *fifo = "event.fifo"; + int socket; + + if (lstat (fifo, &st) == 0) { + if ((st.st_mode & S_IFMT) == S_IFREG) { + errno = EEXIST; + perror("lstat"); + exit (1); + } + } + + unlink (fifo); + if (mkfifo (fifo, 0600) == -1) { + perror("mkfifo"); + exit (1); + } + + /* Linux pipes are broken, we need O_RDWR instead of O_RDONLY */ +#ifdef __linux + socket = open (fifo, O_RDWR | O_NONBLOCK, 0); +#else + socket = open (fifo, O_RDONLY | O_NONBLOCK, 0); +#endif + + if (socket == -1) { + perror("open"); + exit (1); + } + + fprintf(stderr, "Write data to %s\n", fifo); +#endif + /* Initalize the event library */ + event_init(); + + /* Initalize one event */ +#ifdef WIN32 + event_set(&evfifo, (int)socket, EV_READ, fifo_read, &evfifo); +#else + event_set(&evfifo, socket, EV_READ, fifo_read, &evfifo); +#endif + + /* Add it to the active events, without a timeout */ + event_add(&evfifo, NULL); + + event_dispatch(); +#ifdef WIN32 + CloseHandle(socket); +#endif + return (0); +} + diff --git a/libevent/sample/signal-test.c b/libevent/sample/signal-test.c new file mode 100644 index 0000000..7a1fefe --- /dev/null +++ b/libevent/sample/signal-test.c @@ -0,0 +1,57 @@ +/* + * Compile with: + * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent + */ + +#include +#include +#ifndef WIN32 +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include + +#include + +int called = 0; + +void +signal_cb(int fd, short event, void *arg) +{ + struct event *signal = arg; + + printf("%s: got signal %d\n", __func__, EVENT_SIGNAL(signal)); + + if (called >= 2) + event_del(signal); + + called++; +} + +int +main (int argc, char **argv) +{ + struct event signal_int; + + /* Initalize the event library */ + event_init(); + + /* Initalize one event */ + event_set(&signal_int, SIGINT, EV_SIGNAL|EV_PERSIST, signal_cb, + &signal_int); + + event_add(&signal_int, NULL); + + event_dispatch(); + + return (0); +} + diff --git a/libevent/sample/time-test.c b/libevent/sample/time-test.c new file mode 100644 index 0000000..da508ff --- /dev/null +++ b/libevent/sample/time-test.c @@ -0,0 +1,63 @@ +/* + * Compile with: + * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent + */ + +#include +#include +#ifndef WIN32 +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include + +#include + +int lasttime; + +void +timeout_cb(int fd, short event, void *arg) +{ + struct timeval tv; + struct event *timeout = arg; + int newtime = time(NULL); + + printf("%s: called at %d: %d\n", __func__, newtime, + newtime - lasttime); + lasttime = newtime; + + timerclear(&tv); + tv.tv_sec = 2; + event_add(timeout, &tv); +} + +int +main (int argc, char **argv) +{ + struct event timeout; + struct timeval tv; + + /* Initalize the event library */ + event_init(); + + /* Initalize one event */ + evtimer_set(&timeout, timeout_cb, &timeout); + + timerclear(&tv); + tv.tv_sec = 2; + event_add(&timeout, &tv); + + lasttime = time(NULL); + + event_dispatch(); + + return (0); +} + diff --git a/libevent/select.c b/libevent/select.c new file mode 100644 index 0000000..0a47a6a --- /dev/null +++ b/libevent/select.c @@ -0,0 +1,245 @@ +/* $OpenBSD: select.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */ + +/* + * Copyright 2000-2002 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#ifdef HAVE_SYS_TIME_H +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_LOG +#include "log.h" +#else +#define LOG_DBG(x) +#define log_error(x) perror(x) +#endif + +#include "event.h" +#include "evsignal.h" + +extern struct event_list eventqueue; + +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif + +extern volatile sig_atomic_t evsignal_caught; + +struct selectop { + int event_fds; /* Highest fd in fd set */ + int event_fdsz; + fd_set *event_readset; + fd_set *event_writeset; + sigset_t evsigmask; +} sop; + +void *select_init (void); +int select_add (void *, struct event *); +int select_del (void *, struct event *); +int select_recalc (void *, int); +int select_dispatch (void *, struct timeval *); + +const struct eventop selectops = { + "select", + select_init, + select_add, + select_del, + select_recalc, + select_dispatch +}; + +void * +select_init(void) +{ + /* Disable kqueue when this environment variable is set */ + if (getenv("EVENT_NOSELECT")) + return (NULL); + + memset(&sop, 0, sizeof(sop)); + + evsignal_init(&sop.evsigmask); + + return (&sop); +} + +/* + * Called with the highest fd that we know about. If it is 0, completely + * recalculate everything. + */ + +int +select_recalc(void *arg, int max) +{ + struct selectop *sop = arg; + fd_set *readset, *writeset; + struct event *ev; + int fdsz; + + if (sop->event_fds < max) + sop->event_fds = max; + + if (!sop->event_fds) { + TAILQ_FOREACH(ev, &eventqueue, ev_next) + if (ev->ev_fd > sop->event_fds) + sop->event_fds = ev->ev_fd; + } + + fdsz = howmany(sop->event_fds + 1, NFDBITS) * sizeof(fd_mask); + if (fdsz > sop->event_fdsz) { + if ((readset = realloc(sop->event_readset, fdsz)) == NULL) { + log_error("malloc"); + return (-1); + } + + if ((writeset = realloc(sop->event_writeset, fdsz)) == NULL) { + log_error("malloc"); + free(readset); + return (-1); + } + + memset((char *)readset + sop->event_fdsz, 0, + fdsz - sop->event_fdsz); + memset((char *)writeset + sop->event_fdsz, 0, + fdsz - sop->event_fdsz); + + sop->event_readset = readset; + sop->event_writeset = writeset; + sop->event_fdsz = fdsz; + } + + return (evsignal_recalc(&sop->evsigmask)); +} + +int +select_dispatch(void *arg, struct timeval *tv) +{ + int maxfd, res; + struct event *ev, *next; + struct selectop *sop = arg; + + memset(sop->event_readset, 0, sop->event_fdsz); + memset(sop->event_writeset, 0, sop->event_fdsz); + + TAILQ_FOREACH(ev, &eventqueue, ev_next) { + if (ev->ev_events & EV_WRITE) + FD_SET(ev->ev_fd, sop->event_writeset); + if (ev->ev_events & EV_READ) + FD_SET(ev->ev_fd, sop->event_readset); + } + + if (evsignal_deliver(&sop->evsigmask) == -1) + return (-1); + + res = select(sop->event_fds + 1, sop->event_readset, + sop->event_writeset, NULL, tv); + + if (evsignal_recalc(&sop->evsigmask) == -1) + return (-1); + + if (res == -1) { + if (errno != EINTR) { + log_error("select"); + return (-1); + } + + evsignal_process(); + return (0); + } else if (evsignal_caught) + evsignal_process(); + + LOG_DBG((LOG_MISC, 80, "%s: select reports %d", __func__, res)); + + maxfd = 0; + for (ev = TAILQ_FIRST(&eventqueue); ev != NULL; ev = next) { + next = TAILQ_NEXT(ev, ev_next); + + res = 0; + if (FD_ISSET(ev->ev_fd, sop->event_readset)) + res |= EV_READ; + if (FD_ISSET(ev->ev_fd, sop->event_writeset)) + res |= EV_WRITE; + res &= ev->ev_events; + + if (res) { + if (!(ev->ev_events & EV_PERSIST)) + event_del(ev); + event_active(ev, res, 1); + } else if (ev->ev_fd > maxfd) + maxfd = ev->ev_fd; + } + + sop->event_fds = maxfd; + + return (0); +} + +int +select_add(void *arg, struct event *ev) +{ + struct selectop *sop = arg; + + if (ev->ev_events & EV_SIGNAL) + return (evsignal_add(&sop->evsigmask, ev)); + + /* + * Keep track of the highest fd, so that we can calculate the size + * of the fd_sets for select(2) + */ + if (sop->event_fds < ev->ev_fd) + sop->event_fds = ev->ev_fd; + + return (0); +} + +/* + * Nothing to be done here. + */ + +int +select_del(void *arg, struct event *ev) +{ + struct selectop *sop = arg; + + if (!(ev->ev_events & EV_SIGNAL)) + return (0); + + return (evsignal_del(&sop->evsigmask, ev)); +} diff --git a/libevent/signal.c b/libevent/signal.c new file mode 100644 index 0000000..c748927 --- /dev/null +++ b/libevent/signal.c @@ -0,0 +1,162 @@ +/* $OpenBSD: select.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */ + +/* + * Copyright 2000-2002 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ +#include "config.h" + +#include +#ifdef HAVE_SYS_TIME_H +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_LOG +#include "log.h" +#else +#define LOG_DBG(x) +#define log_error(x) perror(x) +#endif + +#include "event.h" +#include "evsignal.h" + +extern struct event_list signalqueue; + +static short evsigcaught[NSIG]; +static int needrecalc; +volatile sig_atomic_t evsignal_caught = 0; + +void evsignal_process(void); +int evsignal_recalc(sigset_t *); +int evsignal_deliver(sigset_t *); + +void +evsignal_init(sigset_t *evsigmask) +{ + sigemptyset(evsigmask); +} + +int +evsignal_add(sigset_t *evsigmask, struct event *ev) +{ + int evsignal; + + if (ev->ev_events & (EV_READ|EV_WRITE)) + errx(1, "%s: EV_SIGNAL incompatible use", __func__); + evsignal = EVENT_SIGNAL(ev); + sigaddset(evsigmask, evsignal); + + return (0); +} + +/* + * Nothing to be done here. + */ + +int +evsignal_del(sigset_t *evsigmask, struct event *ev) +{ + int evsignal; + + evsignal = EVENT_SIGNAL(ev); + sigdelset(evsigmask, evsignal); + needrecalc = 1; + + return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL)); +} + +static void +evsignal_handler(int sig) +{ + evsigcaught[sig]++; + evsignal_caught = 1; +} + +int +evsignal_recalc(sigset_t *evsigmask) +{ + struct sigaction sa; + struct event *ev; + + if (TAILQ_FIRST(&signalqueue) == NULL && !needrecalc) + return (0); + needrecalc = 0; + + if (sigprocmask(SIG_BLOCK, evsigmask, NULL) == -1) + return (-1); + + /* Reinstall our signal handler. */ + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = evsignal_handler; + sa.sa_mask = *evsigmask; + sa.sa_flags |= SA_RESTART; + + TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) { + if (sigaction(EVENT_SIGNAL(ev), &sa, NULL) == -1) + return (-1); + } + return (0); +} + +int +evsignal_deliver(sigset_t *evsigmask) +{ + if (TAILQ_FIRST(&signalqueue) == NULL) + return (0); + + return (sigprocmask(SIG_UNBLOCK, evsigmask, NULL)); + /* XXX - pending signals handled here */ +} + +void +evsignal_process(void) +{ + struct event *ev; + short ncalls; + + TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) { + ncalls = evsigcaught[EVENT_SIGNAL(ev)]; + if (ncalls) { + if (!(ev->ev_events & EV_PERSIST)) + event_del(ev); + event_active(ev, EV_SIGNAL, ncalls); + } + } + + memset(evsigcaught, 0, sizeof(evsigcaught)); + evsignal_caught = 0; +} + diff --git a/libevent/stamp-h.in b/libevent/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/libevent/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/libevent/test/Makefile.am b/libevent/test/Makefile.am new file mode 100644 index 0000000..f763af5 --- /dev/null +++ b/libevent/test/Makefile.am @@ -0,0 +1,23 @@ +AUTOMAKE_OPTIONS = foreign no-dependencies + +LDADD = -L.. -levent +CPPFPLAGS = -I.. +CFLAGS = -I../compat -Wall @CFLAGS@ + +noinst_PROGRAMS = test-init test-eof test-weof test-time regress bench + +test_init_sources = test-init.c +test_eof_sources = test-eof.c +test_weof_sources = test-weof.c +test_time_sources = test-time.c +regress_sources = regress.c +bench_sources = bench.c + +DISTCLEANFILES = *~ + +all: test + +test: test-init test-eof test-weof test-time regress + @./test.sh + +bench test-init test-eof test-weof test-time regress: ../libevent.a diff --git a/libevent/test/Makefile.in b/libevent/test/Makefile.in new file mode 100644 index 0000000..b4c517e --- /dev/null +++ b/libevent/test/Makefile.in @@ -0,0 +1,324 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 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. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +CC = @CC@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ + +AUTOMAKE_OPTIONS = foreign no-dependencies + +LDADD = -L.. -levent +CPPFPLAGS = -I.. +CFLAGS = -I../compat -Wall @CFLAGS@ + +noinst_PROGRAMS = test-init test-eof test-weof test-time regress bench + +test_init_sources = test-init.c +test_eof_sources = test-eof.c +test_weof_sources = test-weof.c +test_time_sources = test-time.c +regress_sources = regress.c +bench_sources = bench.c + +DISTCLEANFILES = *~ +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(noinst_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +test_init_SOURCES = test-init.c +test_init_OBJECTS = test-init.o +test_init_LDADD = $(LDADD) +test_init_DEPENDENCIES = +test_init_LDFLAGS = +test_eof_SOURCES = test-eof.c +test_eof_OBJECTS = test-eof.o +test_eof_LDADD = $(LDADD) +test_eof_DEPENDENCIES = +test_eof_LDFLAGS = +test_weof_SOURCES = test-weof.c +test_weof_OBJECTS = test-weof.o +test_weof_LDADD = $(LDADD) +test_weof_DEPENDENCIES = +test_weof_LDFLAGS = +test_time_SOURCES = test-time.c +test_time_OBJECTS = test-time.o +test_time_LDADD = $(LDADD) +test_time_DEPENDENCIES = +test_time_LDFLAGS = +regress_SOURCES = regress.c +regress_OBJECTS = regress.o +regress_LDADD = $(LDADD) +regress_DEPENDENCIES = +regress_LDFLAGS = +bench_SOURCES = bench.c +bench_OBJECTS = bench.o +bench_LDADD = $(LDADD) +bench_DEPENDENCIES = +bench_LDFLAGS = +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = test-init.c test-eof.c test-weof.c test-time.c regress.c bench.c +OBJECTS = test-init.o test-eof.o test-weof.o test-time.o regress.o bench.o + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +test-init: $(test_init_OBJECTS) $(test_init_DEPENDENCIES) + @rm -f test-init + $(LINK) $(test_init_LDFLAGS) $(test_init_OBJECTS) $(test_init_LDADD) $(LIBS) + +test-eof: $(test_eof_OBJECTS) $(test_eof_DEPENDENCIES) + @rm -f test-eof + $(LINK) $(test_eof_LDFLAGS) $(test_eof_OBJECTS) $(test_eof_LDADD) $(LIBS) + +test-weof: $(test_weof_OBJECTS) $(test_weof_DEPENDENCIES) + @rm -f test-weof + $(LINK) $(test_weof_LDFLAGS) $(test_weof_OBJECTS) $(test_weof_LDADD) $(LIBS) + +test-time: $(test_time_OBJECTS) $(test_time_DEPENDENCIES) + @rm -f test-time + $(LINK) $(test_time_LDFLAGS) $(test_time_OBJECTS) $(test_time_LDADD) $(LIBS) + +regress: $(regress_OBJECTS) $(regress_DEPENDENCIES) + @rm -f regress + $(LINK) $(regress_LDFLAGS) $(regress_OBJECTS) $(regress_LDADD) $(LIBS) + +bench: $(bench_OBJECTS) $(bench_DEPENDENCIES) + @rm -f bench + $(LINK) $(bench_LDFLAGS) $(bench_OBJECTS) $(bench_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = test + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstPROGRAMS clean-compile clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstPROGRAMS distclean-compile distclean-tags \ + distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +all: test + +test: test-init test-eof test-weof test-time regress + @./test.sh + +bench test-init test-eof test-weof test-time regress: ../libevent.a + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libevent/test/bench.c b/libevent/test/bench.c new file mode 100644 index 0000000..61b0502 --- /dev/null +++ b/libevent/test/bench.c @@ -0,0 +1,181 @@ +/* + * Copyright 2003 Niels Provos + * 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. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + * + * + * Mon 03/10/2003 - Modified by Davide Libenzi + * + * Added chain event propagation to improve the sensitivity of + * the measure respect to the event loop efficency. + * + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +static int count, writes, fired; +static int *pipes; +static int num_pipes, num_active, num_writes; +static struct event *events; + + + +void +read_cb(int fd, short which, void *arg) +{ + int idx = (int) arg, widx = idx + 1; + u_char ch; + + count += read(fd, &ch, sizeof(ch)); + if (writes) { + if (widx >= num_pipes) + widx -= num_pipes; + write(pipes[2 * widx + 1], "e", 1); + writes--; + fired++; + } +} + +struct timeval * +run_once(void) +{ + int *cp, i, space; + static struct timeval ts, te; + + for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { + event_del(&events[i]); + event_set(&events[i], cp[0], EV_READ | EV_PERSIST, read_cb, (void *) i); + event_add(&events[i], NULL); + } + + event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK); + + fired = 0; + space = num_pipes / num_active; + space = space * 2; + for (i = 0; i < num_active; i++, fired++) + write(pipes[i * space + 1], "e", 1); + + count = 0; + writes = num_writes; + { int xcount = 0; + gettimeofday(&ts, NULL); + do { + event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK); + xcount++; + } while (count != fired); + gettimeofday(&te, NULL); + + if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count); + } + + timersub(&te, &ts, &te); + + return (&te); +} + +int +main (int argc, char **argv) +{ + struct rlimit rl; + int i, c; + struct timeval *tv; + int *cp; + extern char *optarg; + + num_pipes = 100; + num_active = 1; + num_writes = num_pipes; + while ((c = getopt(argc, argv, "n:a:w:")) != -1) { + switch (c) { + case 'n': + num_pipes = atoi(optarg); + break; + case 'a': + num_active = atoi(optarg); + break; + case 'w': + num_writes = atoi(optarg); + break; + default: + fprintf(stderr, "Illegal argument \"%c\"\n", c); + exit(1); + } + } + + rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50; + if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { + perror("setrlimit"); + exit(1); + } + + events = calloc(num_pipes, sizeof(struct event)); + pipes = calloc(num_pipes * 2, sizeof(int)); + if (events == NULL || pipes == NULL) { + perror("malloc"); + exit(1); + } + + event_init(); + + for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { +#ifdef USE_PIPES + if (pipe(cp) == -1) { +#else + if (socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) { +#endif + perror("pipe"); + exit(1); + } + } + + for (i = 0; i < 25; i++) { + tv = run_once(); + if (tv == NULL) + exit(1); + fprintf(stdout, "%ld\n", + tv->tv_sec * 1000000L + tv->tv_usec); + } + + exit(0); +} diff --git a/libevent/test/regress.c b/libevent/test/regress.c new file mode 100644 index 0000000..7361f22 --- /dev/null +++ b/libevent/test/regress.c @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2003, 2004 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static int pair[2]; +static int test_ok; +static int called; +static char wbuf[4096]; +static char rbuf[4096]; +static int woff; +static int roff; +static int usepersist; +static struct timeval tset; +static struct timeval tcalled; + +#define TEST1 "this is a test" +#define SECONDS 1 + +void +simple_read_cb(int fd, short event, void *arg) +{ + char buf[256]; + int len; + + len = read(fd, buf, sizeof(buf)); + + if (len) { + if (!called) + event_add(arg, NULL); + } else if (called == 1) + test_ok = 1; + + called++; +} + +void +simple_write_cb(int fd, short event, void *arg) +{ + int len; + + len = write(fd, TEST1, strlen(TEST1) + 1); + if (len == -1) + test_ok = 0; + else + test_ok = 1; +} + +void +multiple_write_cb(int fd, short event, void *arg) +{ + struct event *ev = arg; + int len; + + len = 128; + if (woff + len >= sizeof(wbuf)) + len = sizeof(wbuf) - woff; + + len = write(fd, wbuf + woff, len); + if (len == -1) { + fprintf(stderr, "%s: write\n", __func__); + if (usepersist) + event_del(ev); + return; + } + + woff += len; + + if (woff >= sizeof(wbuf)) { + shutdown(fd, SHUT_WR); + if (usepersist) + event_del(ev); + return; + } + + if (!usepersist) + event_add(ev, NULL); +} + +void +multiple_read_cb(int fd, short event, void *arg) +{ + struct event *ev = arg; + int len; + + len = read(fd, rbuf + roff, sizeof(rbuf) - roff); + if (len == -1) + fprintf(stderr, "%s: read\n", __func__); + if (len <= 0) { + if (usepersist) + event_del(ev); + return; + } + + roff += len; + if (!usepersist) + event_add(ev, NULL); +} + +void +timeout_cb(int fd, short event, void *arg) +{ + struct timeval tv; + int diff; + + gettimeofday(&tcalled, NULL); + if (timercmp(&tcalled, &tset, >)) + timersub(&tcalled, &tset, &tv); + else + timersub(&tset, &tcalled, &tv); + + diff = tv.tv_sec*1000 + tv.tv_usec/1000 - SECONDS * 1000; + if (diff < 0) + diff = -diff; + + if (diff < 100) + test_ok = 1; +} + +void +signal_cb(int fd, short event, void *arg) +{ + struct event *ev = arg; + + signal_del(ev); + test_ok = 1; +} + +struct both { + struct event ev; + int nread; +}; + +void +combined_read_cb(int fd, short event, void *arg) +{ + struct both *both = arg; + char buf[128]; + int len; + + len = read(fd, buf, sizeof(buf)); + if (len == -1) + fprintf(stderr, "%s: read\n", __func__); + if (len <= 0) + return; + + both->nread += len; + event_add(&both->ev, NULL); +} + +void +combined_write_cb(int fd, short event, void *arg) +{ + struct both *both = arg; + char buf[128]; + int len; + + len = sizeof(buf); + if (len > both->nread) + len = both->nread; + + len = write(fd, buf, len); + if (len == -1) + fprintf(stderr, "%s: write\n", __func__); + if (len <= 0) { + shutdown(fd, SHUT_WR); + return; + } + + both->nread -= len; + event_add(&both->ev, NULL); +} + +/* Test infrastructure */ + +int +setup_test(char *name) +{ + + fprintf(stdout, "%s", name); + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { + fprintf(stderr, "%s: socketpair\n", __func__); + exit(1); + } + + test_ok = 0; + called = 0; + return (0); +} + +int +cleanup_test(void) +{ + close(pair[0]); + close(pair[1]); + + if (test_ok) + fprintf(stdout, "OK\n"); + else { + fprintf(stdout, "FAILED\n"); + exit(1); + } + + return (0); +} + +void +test1(void) +{ + struct event ev; + + /* Very simple read test */ + setup_test("Simple read: "); + + write(pair[0], TEST1, strlen(TEST1)+1); + shutdown(pair[0], SHUT_WR); + + event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev); + event_add(&ev, NULL); + event_dispatch(); + + cleanup_test(); +} + +void +test2(void) +{ + struct event ev; + + /* Very simple write test */ + setup_test("Simple write: "); + + event_set(&ev, pair[0], EV_WRITE, simple_write_cb, &ev); + event_add(&ev, NULL); + event_dispatch(); + + cleanup_test(); +} + +void +test3(void) +{ + struct event ev, ev2; + int i; + + /* Multiple read and write test */ + setup_test("Multiple read/write: "); + memset(rbuf, 0, sizeof(rbuf)); + for (i = 0; i < sizeof(wbuf); i++) + wbuf[i] = i; + + roff = woff = 0; + usepersist = 0; + + event_set(&ev, pair[0], EV_WRITE, multiple_write_cb, &ev); + event_add(&ev, NULL); + event_set(&ev2, pair[1], EV_READ, multiple_read_cb, &ev2); + event_add(&ev2, NULL); + event_dispatch(); + + if (roff == woff) + test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0; + + cleanup_test(); +} + +void +test4(void) +{ + struct event ev, ev2; + int i; + + /* Multiple read and write test with persist */ + setup_test("Persist read/write: "); + memset(rbuf, 0, sizeof(rbuf)); + for (i = 0; i < sizeof(wbuf); i++) + wbuf[i] = i; + + roff = woff = 0; + usepersist = 1; + + event_set(&ev, pair[0], EV_WRITE|EV_PERSIST, multiple_write_cb, &ev); + event_add(&ev, NULL); + event_set(&ev2, pair[1], EV_READ|EV_PERSIST, multiple_read_cb, &ev2); + event_add(&ev2, NULL); + event_dispatch(); + + if (roff == woff) + test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0; + + cleanup_test(); +} + +void +test5(void) +{ + struct both r1, r2, w1, w2; + + setup_test("Combined read/write: "); + memset(&r1, 0, sizeof(r1)); + memset(&r2, 0, sizeof(r2)); + memset(&w1, 0, sizeof(w1)); + memset(&w2, 0, sizeof(w2)); + + w1.nread = 4096; + w2.nread = 8192; + + event_set(&r1.ev, pair[0], EV_READ, combined_read_cb, &r1); + event_set(&w1.ev, pair[0], EV_WRITE, combined_write_cb, &w1); + event_set(&r2.ev, pair[1], EV_READ, combined_read_cb, &r2); + event_set(&w2.ev, pair[1], EV_WRITE, combined_write_cb, &w2); + event_add(&r1.ev, NULL); + event_add(&w1.ev, NULL); + event_add(&r2.ev, NULL); + event_add(&w2.ev, NULL); + + event_dispatch(); + + if (r1.nread == 8192 && r2.nread == 4096) + test_ok = 1; + + cleanup_test(); +} + +void +test6(void) +{ + struct timeval tv; + struct event ev; + + setup_test("Simple timeout: "); + + tv.tv_usec = 0; + tv.tv_sec = SECONDS; + evtimer_set(&ev, timeout_cb, NULL); + evtimer_add(&ev, &tv); + + gettimeofday(&tset, NULL); + event_dispatch(); + + cleanup_test(); +} + +void +test7(void) +{ + struct event ev; + struct itimerval itv; + + setup_test("Simple signal: "); + signal_set(&ev, SIGALRM, signal_cb, &ev); + signal_add(&ev, NULL); + + memset(&itv, 0, sizeof(itv)); + itv.it_value.tv_sec = 1; + if (setitimer(ITIMER_REAL, &itv, NULL) == -1) + goto skip_simplesignal; + + event_dispatch(); + skip_simplesignal: + signal_del(&ev); + + cleanup_test(); +} + +void +test8(void) +{ + struct timeval tv, tv_start, tv_end; + struct event ev; + + setup_test("Loop exit: "); + + tv.tv_usec = 0; + tv.tv_sec = 60*60*24; + evtimer_set(&ev, timeout_cb, NULL); + evtimer_add(&ev, &tv); + + tv.tv_usec = 0; + tv.tv_sec = 1; + event_loopexit(&tv); + + gettimeofday(&tv_start, NULL); + event_dispatch(); + gettimeofday(&tv_end, NULL); + timersub(&tv_end, &tv_start, &tv_end); + + evtimer_del(&ev); + + if (tv.tv_sec < 2) + test_ok = 1; + + cleanup_test(); +} + +void +readcb(struct bufferevent *bev, void *arg) +{ + if (EVBUFFER_LENGTH(bev->input) == 4096) { + bufferevent_disable(bev, EV_READ); + test_ok++; + } +} + +void +writecb(struct bufferevent *bev, void *arg) +{ + if (EVBUFFER_LENGTH(bev->output) == 0) + test_ok++; +} + +void +errorcb(struct bufferevent *bev, short what, void *arg) +{ + test_ok = -2; +} + +void +test9(void) +{ + struct bufferevent *bev1, *bev2; + char buffer[4096]; + int i; + + setup_test("Bufferevent: "); + + bev1 = bufferevent_new(pair[0], readcb, writecb, errorcb, NULL); + bev2 = bufferevent_new(pair[1], readcb, writecb, errorcb, NULL); + + bufferevent_disable(bev1, EV_READ); + bufferevent_enable(bev2, EV_READ); + + for (i = 0; i < sizeof(buffer); i++) + buffer[0] = i; + + bufferevent_write(bev1, buffer, sizeof(buffer)); + + event_dispatch(); + + bufferevent_free(bev1); + bufferevent_free(bev2); + + if (test_ok != 2) + test_ok = 0; + + cleanup_test(); +} + +int +main (int argc, char **argv) +{ + setvbuf(stdout, NULL, _IONBF, 0); + + /* Initalize the event library */ + event_init(); + + test1(); + + test2(); + + test3(); + + test4(); + + test5(); + + test6(); + + test7(); + + test8(); + + test9(); + + return (0); +} + diff --git a/libevent/test/test-eof.c b/libevent/test/test-eof.c new file mode 100644 index 0000000..020c661 --- /dev/null +++ b/libevent/test/test-eof.c @@ -0,0 +1,68 @@ +/* + * Compile with: + * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int test_okay = 1; +int called = 0; + +void +read_cb(int fd, short event, void *arg) +{ + char buf[256]; + int len; + + len = read(fd, buf, sizeof(buf)); + + printf("%s: read %d%s\n", __func__, + len, len ? "" : " - means EOF"); + + if (len) { + if (!called) + event_add(arg, NULL); + } else if (called == 1) + test_okay = 0; + + called++; +} + +int +main (int argc, char **argv) +{ + struct event ev; + char *test = "test string"; + int pair[2]; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) + return (1); + + + write(pair[0], test, strlen(test)+1); + shutdown(pair[0], SHUT_WR); + + /* Initalize the event library */ + event_init(); + + /* Initalize one event */ + event_set(&ev, pair[1], EV_READ, read_cb, &ev); + + event_add(&ev, NULL); + + event_dispatch(); + + return (test_okay); +} + diff --git a/libevent/test/test-init.c b/libevent/test/test-init.c new file mode 100644 index 0000000..32806ba --- /dev/null +++ b/libevent/test/test-init.c @@ -0,0 +1,27 @@ +/* + * Compile with: + * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int +main(int argc, char **argv) +{ + /* Initalize the event library */ + event_init(); + + return (0); +} + diff --git a/libevent/test/test-time.c b/libevent/test/test-time.c new file mode 100644 index 0000000..a26c973 --- /dev/null +++ b/libevent/test/test-time.c @@ -0,0 +1,68 @@ +/* + * Compile with: + * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int called = 0; + +#define NEVENT 20000 + +struct event *ev[NEVENT]; + +void +time_cb(int fd, short event, void *arg) +{ + struct timeval tv; + int i, j; + + called++; + + if (called < 10*NEVENT) { + for (i = 0; i < 10; i++) { + j = random() % NEVENT; + tv.tv_sec = 0; + tv.tv_usec = random() % 50000L; + if (tv.tv_usec % 2) + evtimer_add(ev[j], &tv); + else + evtimer_del(ev[j]); + } + } +} + +int +main (int argc, char **argv) +{ + struct timeval tv; + int i; + + /* Initalize the event library */ + event_init(); + + for (i = 0; i < NEVENT; i++) { + ev[i] = malloc(sizeof(struct event)); + + /* Initalize one event */ + evtimer_set(ev[i], time_cb, ev[i]); + tv.tv_sec = 0; + tv.tv_usec = random() % 50000L; + evtimer_add(ev[i], &tv); + } + + event_dispatch(); + + return (called < NEVENT); +} + diff --git a/libevent/test/test-weof.c b/libevent/test/test-weof.c new file mode 100644 index 0000000..8862b4a --- /dev/null +++ b/libevent/test/test-weof.c @@ -0,0 +1,68 @@ +/* + * Compile with: + * cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int pair[2]; +int test_okay = 1; +int called = 0; + +void +write_cb(int fd, short event, void *arg) +{ + char *test = "test string"; + int len; + + len = write(fd, test, strlen(test) + 1); + + printf("%s: write %d%s\n", __func__, + len, len ? "" : " - means EOF"); + + if (len > 0) { + if (!called) + event_add(arg, NULL); + close(pair[0]); + } else if (called == 1) + test_okay = 0; + + called++; +} + +int +main (int argc, char **argv) +{ + struct event ev; + + if (signal(SIGPIPE, SIG_IGN) == SIG_IGN) + return (1); + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) + return (1); + + /* Initalize the event library */ + event_init(); + + /* Initalize one event */ + event_set(&ev, pair[1], EV_WRITE, write_cb, &ev); + + event_add(&ev, NULL); + + event_dispatch(); + + return (test_okay); +} + diff --git a/libevent/test/test.sh b/libevent/test/test.sh new file mode 100755 index 0000000..f76dc2a --- /dev/null +++ b/libevent/test/test.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +setup () { + export EVENT_NOKQUEUE=yes + export EVENT_NOPOLL=yes + export EVENT_NOSELECT=yes + export EVENT_NOEPOLL=yes + export EVENT_NORTSIG=yes +} + +test () { + if ! ./test-init 2>/dev/null ; + then + echo Skipping test + return + fi + +echo -n " test-eof: " +if ./test-eof >/dev/null ; +then + echo OKAY ; +else + echo FAILED ; +fi +echo -n " test-weof: " +if ./test-weof >/dev/null ; +then + echo OKAY ; +else + echo FAILED ; +fi +echo -n " test-time: " +if ./test-time >/dev/null ; +then + echo OKAY ; +else + echo FAILED ; +fi +echo -n " regress: " +if ./regress >/dev/null ; +then + echo OKAY ; +else + echo FAILED ; +fi +} + +echo "Running tests:" + +# Need to do this by hand? +setup +unset EVENT_NOKQUEUE +echo "KQUEUE" +test + +setup +unset EVENT_NOPOLL +echo "POLL" +test + +setup +unset EVENT_NOSELECT +echo "SELECT" +test + +setup +unset EVENT_NORTSIG +echo "RTSIG" +test + +setup +unset EVENT_NOEPOLL +echo "EPOLL" +test + + + diff --git a/list.c b/list.c new file mode 100644 index 0000000..23d3e04 --- /dev/null +++ b/list.c @@ -0,0 +1,848 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** Portions borrowed from kazlib. Header follows: +*/ + + +/* + * List Abstract Data Type + * Copyright (C) 1997 Kaz Kylheku + * + * Free Software License: + * + * All rights are reserved by the author, with the following exceptions: + * Permission is granted to freely reproduce and distribute this software, + * possibly in exchange for a fee, provided that this copyright notice appears + * intact. Permission is also granted to adapt this software to produce + * derivative works, as long as the modified versions carry this copyright + * notice and additional notices stating that the work has been modified. + * This source code may be translated into executable form and incorporated + * into proprietary software; there is no requirement for such software to + * contain a copyright notice related to this source. + * + * $Id$ + * $Name: $ + */ + + +#include +#include +#include +#include +#define LIST_IMPLEMENTATION +#include "list.h" +#include "log.h" + +#define next list_next +#define prev list_prev +#define data list_data + +#define pool list_pool +#define fre list_free +#define size list_size + +#define nilnode list_nilnode +#define nodecount list_nodecount +#define maxcount list_maxcount + +#define list_nil(L) (&(L)->nilnode) +#define list_first_priv(L) ((L)->nilnode.next) +#define list_last_priv(L) ((L)->nilnode.prev) +#define lnode_next(N) ((N)->next) +#define lnode_prev(N) ((N)->prev) + +#ifdef KAZLIB_RCSID +static const char rcsid[] = "$Id$"; +#endif + +/* + * Initialize a list object supplied by the client such that it becomes a valid + * empty list. If the list is to be ``unbounded'', the maxcount should be + * specified as LISTCOUNT_T_MAX, or, alternately, as -1. The value zero + * is not permitted. + */ + +list_t * +list_init (list_t * list, listcount_t maxcount) +{ + nassert (maxcount != 0); + list->nilnode.next = &list->nilnode; + list->nilnode.prev = &list->nilnode; + list->nodecount = 0; + list->maxcount = maxcount; + return list; +} + +/* + * Dynamically allocate a list object using malloc(), and initialize it so that + * it is a valid empty list. If the list is to be ``unbounded'', the maxcount + * should be specified as LISTCOUNT_T_MAX, or, alternately, as -1. + */ + +list_t * +list_create (listcount_t maxcount) +{ + list_t *new = malloc (sizeof *new); + if (new) { + nassert (maxcount != 0); + new->nilnode.next = &new->nilnode; + new->nilnode.prev = &new->nilnode; + new->nodecount = 0; + new->maxcount = maxcount; + } + return new; +} + +/* + * Destroy a dynamically allocated list object. + * The client must remove the nodes first. + */ + +void +list_destroy (list_t * list) +{ + nassert (list_isempty (list)); + free (list); +} + +/* + * Free all of the nodes of a list. The list must contain only + * dynamically allocated nodes. After this call, the list + * is empty. + */ + +void +list_destroy_nodes (list_t * list) +{ + lnode_t *lnode = list_first_priv (list), *nil = list_nil (list), *tmp; + + while (lnode != nil) { + tmp = lnode->next; + lnode->next = NULL; + lnode->prev = NULL; + lnode_destroy (lnode); + lnode = tmp; + } + + list_init (list, list->maxcount); +} + +/* + * Return all of the nodes of a list to a node pool. The nodes in + * the list must all have come from the same pool. + */ + +void +list_return_nodes (list_t * list, lnodepool_t * pool) +{ + lnode_t *lnode = list_first_priv (list), *tmp, *nil = list_nil (list); + + while (lnode != nil) { + tmp = lnode->next; + lnode->next = NULL; + lnode->prev = NULL; + lnode_return (pool, lnode); + lnode = tmp; + } + + list_init (list, list->maxcount); +} + +/* + * Insert the node ``new'' into the list immediately after ``this'' node. + */ + +void +list_ins_after (list_t * list, lnode_t * new, lnode_t * this) +{ + lnode_t *that = this->next; + + nassert (new != NULL); + nassert (!list_contains (list, new)); + nassert (!lnode_is_in_a_list (new)); + nassert (this == list_nil (list) || list_contains (list, this)); + nassert (list->nodecount + 1 > list->nodecount); + + new->prev = this; + new->next = that; + that->prev = new; + this->next = new; + list->nodecount++; + + nassert (list->nodecount <= list->maxcount); +} + +/* + * Insert the node ``new'' into the list immediately before ``this'' node. + */ + +void +list_ins_before (list_t * list, lnode_t * new, lnode_t * this) +{ + lnode_t *that = this->prev; + + nassert (new != NULL); + nassert (!list_contains (list, new)); + nassert (!lnode_is_in_a_list (new)); + nassert (this == list_nil (list) || list_contains (list, this)); + nassert (list->nodecount + 1 > list->nodecount); + + new->next = this; + new->prev = that; + that->next = new; + this->prev = new; + list->nodecount++; + + nassert (list->nodecount <= list->maxcount); +} + +/* + * Delete the given node from the list. + */ + +lnode_t * +list_delete (list_t * list, lnode_t * del) +{ + lnode_t *next = del->next; + lnode_t *prev = del->prev; + + nassert (list_contains (list, del)); + + prev->next = next; + next->prev = prev; + list->nodecount--; + + del->next = del->prev = NULL; + + return del; +} + +/* + * For each node in the list, execute the given function. The list, + * current node and the given context pointer are passed on each + * call to the function. + */ + +void +list_process (list_t * list, void *context, void (*function) (list_t * list, lnode_t * lnode, void *context)) +{ + lnode_t *node = list_first_priv (list), *next, *nil = list_nil (list); + + while (node != nil) { + /* check for callback function deleting */ + /* the next node from under us */ + nassert (list_contains (list, node)); + next = node->next; + function (list, node, context); + node = next; + } +} + +/* + * Dynamically allocate a list node and assign it the given piece of data. + */ + +lnode_t * +lnode_create (void *data) +{ + lnode_t *new = malloc (sizeof *new); + if (new) { + new->data = data; + new->next = NULL; + new->prev = NULL; + } + return new; +} + +/* + * Initialize a user-supplied lnode. + */ + +lnode_t * +lnode_init (lnode_t * lnode, void *data) +{ + lnode->data = data; + lnode->next = NULL; + lnode->prev = NULL; + return lnode; +} + +/* + * Destroy a dynamically allocated node. + */ + +void +lnode_destroy (lnode_t * lnode) +{ + nassert (!lnode_is_in_a_list (lnode)); + free (lnode); +} + +/* + * Initialize a node pool object to use a user-supplied set of nodes. + * The ``nodes'' pointer refers to an array of lnode_t objects, containing + * ``n'' elements. + */ + +lnodepool_t * +lnode_pool_init (lnodepool_t * pool, lnode_t * nodes, listcount_t n) +{ + listcount_t i; + + nassert (n != 0); + + pool->pool = nodes; + pool->fre = nodes; + pool->size = n; + for (i = 0; i < n - 1; i++) { + nodes[i].next = nodes + i + 1; + } + nodes[i].next = NULL; + nodes[i].prev = nodes; /* to make sure node is marked ``on list'' */ + return pool; +} + +/* + * Create a dynamically allocated pool of n nodes. + */ + +lnodepool_t * +lnode_pool_create (listcount_t n) +{ + lnodepool_t *pool; + lnode_t *nodes; + + nassert (n != 0); + + pool = malloc (sizeof *pool); + if (!pool) + return NULL; + nodes = malloc (n * sizeof *nodes); + if (!nodes) { + free (pool); + return NULL; + } + lnode_pool_init (pool, nodes, n); + return pool; +} + +/* + * Determine whether the given pool is from this pool. + */ + +int +lnode_pool_isfrom (lnodepool_t * pool, lnode_t * node) +{ + listcount_t i; + + /* this is carefully coded this way because ANSI C forbids pointers + to different objects from being subtracted or compared other + than for exact equality */ + + for (i = 0; i < pool->size; i++) { + if (pool->pool + i == node) + return 1; + } + return 0; +} + +/* + * Destroy a dynamically allocated pool of nodes. + */ + +void +lnode_pool_destroy (lnodepool_t * p) +{ + free (p->pool); + free (p); +} + +/* + * Borrow a node from a node pool. Returns a null pointer if the pool + * is exhausted. + */ + +lnode_t * +lnode_borrow (lnodepool_t * pool, void *data) +{ + lnode_t *new = pool->fre; + if (new) { + pool->fre = new->next; + new->data = data; + new->next = NULL; + new->prev = NULL; + } + return new; +} + +/* + * Return a node to a node pool. A node must be returned to the pool + * from which it came. + */ + +void +lnode_return (lnodepool_t * pool, lnode_t * node) +{ + nassert (lnode_pool_isfrom (pool, node)); + nassert (!lnode_is_in_a_list (node)); + + node->next = pool->fre; + node->prev = node; + pool->fre = node; +} + +/* + * Determine whether the given list contains the given node. + * According to this function, a list does not contain its nilnode. + */ + +int +list_contains (list_t * list, lnode_t * node) +{ + lnode_t *n, *nil = list_nil (list); + + for (n = list_first_priv (list); n != nil; n = lnode_next (n)) { + if (node == n) + return 1; + } + + return 0; +} + +/* + * A more generalized variant of list_transfer. This one removes a + * ``slice'' from the source list and appends it to the destination + * list. + */ + +void +list_extract (list_t * dest, list_t * source, lnode_t * first, lnode_t * last) +{ + listcount_t moved = 1; + + nassert (first == NULL || list_contains (source, first)); + nassert (last == NULL || list_contains (source, last)); + + if (first == NULL || last == NULL) + return; + + /* adjust the destination list so that the slice is spliced out */ + + first->prev->next = last->next; + last->next->prev = first->prev; + + /* graft the splice at the end of the dest list */ + + last->next = &dest->nilnode; + first->prev = dest->nilnode.prev; + dest->nilnode.prev->next = first; + dest->nilnode.prev = last; + + while (first != last) { + first = first->next; + nassert (first != list_nil (source)); /* oops, last before first! */ + moved++; + } + + /* nassert no overflows */ + nassert (source->nodecount - moved <= source->nodecount); + nassert (dest->nodecount + moved >= dest->nodecount); + + /* nassert no weirdness */ + nassert (moved <= source->nodecount); + + source->nodecount -= moved; + dest->nodecount += moved; + + /* nassert list sanity */ + nassert (list_verify (source)); + nassert (list_verify (dest)); +} + + +/* + * Split off a trailing sequence of nodes from the source list and relocate + * them to the tail of the destination list. The trailing sequence begins + * with node ``first'' and terminates with the last node of the source + * list. The nodes are added to the end of the new list in their original + * order. + */ + +void +list_transfer (list_t * dest, list_t * source, lnode_t * first) +{ + listcount_t moved = 1; + lnode_t *last; + + nassert (first == NULL || list_contains (source, first)); + + if (first == NULL) + return; + + last = source->nilnode.prev; + + source->nilnode.prev = first->prev; + first->prev->next = &source->nilnode; + + last->next = &dest->nilnode; + first->prev = dest->nilnode.prev; + dest->nilnode.prev->next = first; + dest->nilnode.prev = last; + + while (first != last) { + first = first->next; + moved++; + } + + /* nassert no overflows */ + nassert (source->nodecount - moved <= source->nodecount); + nassert (dest->nodecount + moved >= dest->nodecount); + + /* nassert no weirdness */ + nassert (moved <= source->nodecount); + + source->nodecount -= moved; + dest->nodecount += moved; + + /* nassert list sanity */ + nassert (list_verify (source)); + nassert (list_verify (dest)); +} + +void +list_merge (list_t * dest, list_t * sour, int compare (const void *, const void *)) +{ + lnode_t *dn, *sn, *tn; + lnode_t *d_nil = list_nil (dest), *s_nil = list_nil (sour); + + /* Nothing to do if source and destination list are the same. */ + if (dest == sour) + return; + + /* overflow check */ + nassert (list_count (sour) + list_count (dest) >= list_count (sour)); + + /* lists must be sorted */ + nassert (list_is_sorted (sour, compare)); + nassert (list_is_sorted (dest, compare)); + + dn = list_first_priv (dest); + sn = list_first_priv (sour); + + while (dn != d_nil && sn != s_nil) { + if (compare (lnode_get (dn), lnode_get (sn)) >= 0) { + tn = lnode_next (sn); + list_delete (sour, sn); + list_ins_before (dest, sn, dn); + sn = tn; + } else { + dn = lnode_next (dn); + } + } + + if (dn != d_nil) + return; + + if (sn != s_nil) + list_transfer (dest, sour, sn); +} + +void +list_sort (list_t * list, int compare (const void *, const void *)) +{ + list_t extra; + listcount_t middle; + lnode_t *node; + + if (list_count (list) > 1) { + middle = list_count (list) / 2; + node = list_first_priv (list); + + list_init (&extra, list_count (list) - middle); + + while (middle--) + node = lnode_next (node); + + list_transfer (&extra, list, node); + list_sort (list, compare); + list_sort (&extra, compare); + list_merge (list, &extra, compare); + } + nassert (list_is_sorted (list, compare)); +} + +lnode_t * +list_find (list_t * list, const void *key, int compare (const void *, const void *)) +{ + lnode_t *node; + + for (node = list_first_priv (list); node != list_nil (list); node = node->next) { + if (compare (lnode_get (node), key) == 0) + return node; + } + + return 0; +} + + +/* + * Return 1 if the list is in sorted order, 0 otherwise + */ + +int +list_is_sorted (list_t * list, int compare (const void *, const void *)) +{ + lnode_t *node, *next, *nil; + + next = nil = list_nil (list); + node = list_first_priv (list); + + if (node != nil) + next = lnode_next (node); + + for (; next != nil; node = next, next = lnode_next (next)) { + if (compare (lnode_get (node), lnode_get (next)) > 0) + return 0; + } + + return 1; +} + +/* + * Get rid of macro functions definitions so they don't interfere + * with the actual definitions + */ + +#undef list_isempty +#undef list_isfull +#undef lnode_pool_isempty +#undef list_append +#undef list_prepend +#undef list_first +#undef list_last +#undef list_next +#undef list_prev +#undef list_count +#undef list_del_first +#undef list_del_last +#undef lnode_put +#undef lnode_get + +/* + * Return 1 if the list is empty, 0 otherwise + */ + +int +list_isempty (list_t * list) +{ + return list->nodecount == 0; +} + +/* + * Return 1 if the list is full, 0 otherwise + * Permitted only on bounded lists. + */ + +int +list_isfull (list_t * list) +{ + return list->nodecount == list->maxcount; +} + +/* + * Check if the node pool is empty. + */ + +int +lnode_pool_isempty (lnodepool_t * pool) +{ + return (pool->fre == NULL); +} + +/* + * Add the given node at the end of the list + */ + +void +list_append (list_t * list, lnode_t * node) +{ + list_ins_before (list, node, &list->nilnode); +} + +/* + * Add the given node at the beginning of the list. + */ + +void +list_prepend (list_t * list, lnode_t * node) +{ + list_ins_after (list, node, &list->nilnode); +} + +/* + * Retrieve the first node of the list + */ + +lnode_t * +list_first (list_t * list) +{ + if (list->nilnode.next == &list->nilnode) + return NULL; + return list->nilnode.next; +} + +/* + * Retrieve the last node of the list + */ + +lnode_t * +list_last (list_t * list) +{ + if (list->nilnode.prev == &list->nilnode) + return NULL; + return list->nilnode.prev; +} + +/* + * Retrieve the count of nodes in the list + */ + +listcount_t +list_count (list_t * list) +{ + return list->nodecount; +} + +/* + * Remove the first node from the list and return it. + */ + +lnode_t * +list_del_first (list_t * list) +{ + return list_delete (list, list->nilnode.next); +} + +/* + * Remove the last node from the list and return it. + */ + +lnode_t * +list_del_last (list_t * list) +{ + return list_delete (list, list->nilnode.prev); +} + + +/* + * Associate a data item with the given node. + */ + +void +lnode_put (lnode_t * lnode, void *data) +{ + lnode->data = data; +} + +/* + * Retrieve the data item associated with the node. + */ + +void * +lnode_get (lnode_t * lnode) +{ + return lnode->data; +} + +/* + * Retrieve the node's successor. If there is no successor, + * NULL is returned. + */ + +lnode_t * +list_next (list_t * list, lnode_t * lnode) +{ + nassert (list_contains (list, lnode)); + + if (lnode->next == list_nil (list)) + return NULL; + return lnode->next; +} + +/* + * Retrieve the node's predecessor. See comment for lnode_next(). + */ + +lnode_t * +list_prev (list_t * list, lnode_t * lnode) +{ + nassert (list_contains (list, lnode)); + + if (lnode->prev == list_nil (list)) + return NULL; + return lnode->prev; +} + +/* + * Return 1 if the lnode is in some list, otherwise return 0. + */ + +int +lnode_is_in_a_list (lnode_t * lnode) +{ + return (lnode->next != NULL || lnode->prev != NULL); +} + + +int +list_verify (list_t * list) +{ + lnode_t *node = list_first_priv (list), *nil = list_nil (list); + listcount_t count = list_count (list); + + if (node->prev != nil) { + return 0; + } + if (count > list->maxcount) { + return 0; + } + + while (node != nil && count--) { + if (node->next->prev != node) { + return 0; + } + node = node->next; + } + + if (count != 0 || node != nil) { + return 0; + } + + return 1; +} + +int +comparef (const void *key1, const void *key2) +{ + return strcasecmp (key1, key2); +} + + + diff --git a/list.h b/list.h new file mode 100644 index 0000000..154f663 --- /dev/null +++ b/list.h @@ -0,0 +1,179 @@ +/* NeoStats - IRC Statistical Services Copyright (c) 1999-2002 NeoStats Group Inc. +** Copyright (c) 1999-2002 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** Portions borrowed from kazlib. Original Header follows: +*/ +/* + * List Abstract Data Type + * Copyright (C) 1997 Kaz Kylheku + * + * Free Software License: + * + * All rights are reserved by the author, with the following exceptions: + * Permission is granted to freely reproduce and distribute this software, + * possibly in exchange for a fee, provided that this copyright notice appears + * intact. Permission is also granted to adapt this software to produce + * derivative works, as long as the modified versions carry this copyright + * notice and additional notices stating that the work has been modified. + * This source code may be translated into executable form and incorporated + * into proprietary software; there is no requirement for such software to + * contain a copyright notice related to this source. + * + * $Id$ + * $Name: $ + */ + +#ifndef LIST_H +#define LIST_H + +#include + +#ifdef KAZLIB_SIDEEFFECT_DEBUG +#include "sfx.h" +#define LIST_SFX_CHECK(E) SFX_CHECK(E) +#else +#define LIST_SFX_CHECK(E) (E) +#endif + +/* + * Blurb for inclusion into C++ translation units + */ + +#ifdef __cplusplus +extern "C" { +#endif + + typedef unsigned long listcount_t; +#define LISTCOUNT_T_MAX ULONG_MAX + + typedef struct lnode_t { +#if defined(LIST_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) + struct lnode_t *list_next; + struct lnode_t *list_prev; + void *list_data; +#else + int list_dummy; +#endif + } lnode_t; + + typedef struct lnodepool_t { +#if defined(LIST_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) + struct lnode_t *list_pool; + struct lnode_t *list_free; + listcount_t list_size; +#else + int list_dummy; +#endif + } lnodepool_t; + + typedef struct list_t { +#if defined(LIST_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) + lnode_t list_nilnode; + listcount_t list_nodecount; + listcount_t list_maxcount; +#else + int list_dummy; +#endif + } list_t; + + lnode_t *lnode_create (void *); + lnode_t *lnode_init (lnode_t *, void *); + void lnode_destroy (lnode_t *); + void lnode_put (lnode_t *, void *); + void *lnode_get (lnode_t *); + int lnode_is_in_a_list (lnode_t *); + +#if defined(LIST_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) +#define lnode_put(N, D) ((N)->list_data = (D)) +#define lnode_get(N) ((N)->list_data) +#endif + + lnodepool_t *lnode_pool_init (lnodepool_t *, lnode_t *, listcount_t); + lnodepool_t *lnode_pool_create (listcount_t); + void lnode_pool_destroy (lnodepool_t *); + lnode_t *lnode_borrow (lnodepool_t *, void *); + void lnode_return (lnodepool_t *, lnode_t *); + int lnode_pool_isempty (lnodepool_t *); + int lnode_pool_isfrom (lnodepool_t *, lnode_t *); + + int comparef (const void *, const void *); + + + list_t *list_init (list_t *, listcount_t); + list_t *list_create (listcount_t); + void list_destroy (list_t *); + void list_destroy_nodes (list_t *); + void list_return_nodes (list_t *, lnodepool_t *); + + listcount_t list_count (list_t *); + int list_isempty (list_t *); + int list_isfull (list_t *); + int list_contains (list_t *, lnode_t *); + + void list_append (list_t *, lnode_t *); + void list_prepend (list_t *, lnode_t *); + void list_ins_before (list_t *, lnode_t *, lnode_t *); + void list_ins_after (list_t *, lnode_t *, lnode_t *); + + lnode_t *list_first (list_t *); + lnode_t *list_last (list_t *); + lnode_t *list_next (list_t *, lnode_t *); + lnode_t *list_prev (list_t *, lnode_t *); + + lnode_t *list_del_first (list_t *); + lnode_t *list_del_last (list_t *); + lnode_t *list_delete (list_t *, lnode_t *); + + void list_process (list_t *, void *, void (*)(list_t *, lnode_t *, void *)); + + int list_verify (list_t *); + +#if defined(LIST_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) +#define lnode_pool_isempty(P) ((P)->list_free == 0) +#define list_count(L) ((L)->list_nodecount) +#define list_isempty(L) ((L)->list_nodecount == 0) +#define list_isfull(L) (LIST_SFX_CHECK(L)->list_nodecount == (L)->list_maxcount) +#define list_next(L, N) (LIST_SFX_CHECK(N)->list_next == &(L)->list_nilnode ? NULL : (N)->list_next) +#define list_prev(L, N) (LIST_SFX_CHECK(N)->list_prev == &(L)->list_nilnode ? NULL : (N)->list_prev) +#define list_first(L) list_next(LIST_SFX_CHECK(L), &(L)->list_nilnode) +#define list_last(L) list_prev(LIST_SFX_CHECK(L), &(L)->list_nilnode) +#endif + +#if defined(LIST_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG) +#define list_append(L, N) list_ins_before(LIST_SFX_CHECK(L), N, &(L)->list_nilnode) +#define list_prepend(L, N) list_ins_after(LIST_SFX_CHECK(L), N, &(L)->list_nilnode) +#define list_del_first(L) list_delete(LIST_SFX_CHECK(L), list_first(L)) +#define list_del_last(L) list_delete(LIST_SFX_CHECK(L), list_last(L)) +#endif + +/* destination list on the left, source on the right */ + + void list_extract (list_t *, list_t *, lnode_t *, lnode_t *); + void list_transfer (list_t *, list_t *, lnode_t * first); + void list_merge (list_t *, list_t *, int (const void *, const void *)); + void list_sort (list_t *, int (const void *, const void *)); + lnode_t *list_find (list_t *, const void *, int (const void *, const void *)); + int list_is_sorted (list_t *, int (const void *, const void *)); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/log.c b/log.c new file mode 100644 index 0000000..d7ff559 --- /dev/null +++ b/log.c @@ -0,0 +1,269 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + +#include "config.h" +#include "defines.h" +#include "conf.h" +#include "hash.h" +#include "log.h" +#include "dotconf.h" +#ifdef HAVE_BACKTRACE +#include +#endif + +const char* CoreLogFileName="MQServer"; +char LogFileNameFormat[MAX_LOGFILENAME]="-%m-%d"; + +const char *loglevels[10] = { + "CRITICAL", + "ERROR", + "WARNING", + "NOTICE", + "NORMAL", + "INFO", + "DEBUG1", + "DEBUG2", + "DEBUG3", + "INSANE" +}; + +static char log_buf[BUFSIZE]; +static char log_fmttime[TIMEBUFSIZE]; + +struct logs_ { + FILE *logfile; + char name[BUFSIZE]; + char logname[MAXPATH]; + unsigned int flush; +} logs_; + +hash_t *logs; + +/** @brief initialize the logging functions + */ +int +init_logs () +{ + SET_SEGV_LOCATION(); + logs = hash_create (-1, 0, 0); + if (!logs) { + printf ("ERROR: Can't initialize log subsystem. Exiting!"); + return NS_FAILURE; + } + printf("Logging Subsystem Started\n"); + return NS_SUCCESS; +} + +/** @brief Occasionally flush log files out + */ +void +close_logs () +{ + hscan_t hs; + hnode_t *hn; + struct logs_ *logentry; + + SET_SEGV_LOCATION(); + hash_scan_begin (&hs, logs); + while ((hn = hash_scan_next (&hs)) != NULL) { + logentry = hnode_get (hn); + logentry->flush = 0; +#ifdef DEBUG + printf ("Closing Logfile %s (%s)\n", logentry->name, (char *) hnode_getkey (hn)); +#endif + if(logentry->logfile) + { + fflush (logentry->logfile); + fclose (logentry->logfile); + logentry->logfile = NULL; + } + hash_scan_delete (logs, hn); + hnode_destroy (hn); + free (logentry); + } +} + +void +fini_logs() { + hscan_t hs; + hnode_t *hn; + struct logs_ *logentry; + + SET_SEGV_LOCATION(); + hash_scan_begin (&hs, logs); + while ((hn = hash_scan_next (&hs)) != NULL) { + logentry = hnode_get (hn); + logentry->flush = 0; +#ifdef DEBUG + printf ("Closing Logfile %s (%s)\n", logentry->name, (char *) hnode_getkey (hn)); +#endif + if(logentry->logfile) + { + fflush (logentry->logfile); + fclose (logentry->logfile); + logentry->logfile = NULL; + } + hash_scan_delete (logs, hn); + hnode_destroy (hn); + free (logentry); + } + /* for some reason, the logs are not getting flushed correctly */ + hash_destroy(logs); +} + +void make_log_filename(char* modname, char *logname) +{ + time_t t = time(NULL); + strftime (log_fmttime, TIMEBUFSIZE, LogFileNameFormat, localtime (&t)); +// strlwr(modname); + snprintf (logname, MAXPATH, "logs/%s%s.log", modname, log_fmttime); +} + +/** @Configurable logging function + */ +void +nlog (int level, int scope, char *fmt, ...) +{ + va_list ap; + hnode_t *hn; + struct logs_ *logentry; + + if (level <= config.debug) { + /* if scope is > 0, then log to a diff file */ + if (scope > 0) { + if (segv_inmodule[0] != 0) { + hn = hash_lookup (logs, segv_inmodule); + } else { +#if 0 + nlog (LOG_ERROR, LOG_CORE, "Warning, nlog called with LOG_MOD, but segv_inmodule is blank! Logging to Core"); +#endif + hn = hash_lookup (logs, CoreLogFileName); + } + } else { + hn = hash_lookup (logs, CoreLogFileName); + } + if (hn) { + /* we found our log entry */ + logentry = hnode_get (hn); + if(!logentry->logfile) + logentry->logfile = fopen (logentry->logname, "a"); + } else { + /* log file not found */ + if (segv_inmodule[0] == 0 && (scope > 0)) { +#ifdef DEBUG + printf ("segv_inmodule is blank, but scope is for Modules!\n"); +#endif + /* bad, but hey ! */ + scope = 0; + } + logentry = malloc (sizeof (struct logs_)); + strncpy (logentry->name, scope > 0 ? segv_inmodule : CoreLogFileName, BUFSIZE); + make_log_filename(logentry->name, logentry->logname); + logentry->logfile = fopen (logentry->logname, "a"); + logentry->flush = 0; + hn = hnode_create (logentry); + hash_insert (logs, hn, logentry->name); + + } + +#ifdef DEBUG + if (!logentry->logfile) { + printf ("LOG ERROR: %s\n", strerror (errno)); + do_exit (NS_EXIT_NORMAL, NULL); + } +#endif + /* we update me.now here, becase some functions might be busy and not call the loop a lot */ + me.now = time(NULL); + snprintf (me.strnow, STR_TIME_T_SIZE, "%ld", me.now); + strftime (log_fmttime, TIMEBUFSIZE, "%d/%m/%Y[%H:%M:%S]", localtime (&me.now)); + va_start (ap, fmt); + vsnprintf (log_buf, BUFSIZE, fmt, ap); + va_end (ap); + + fprintf (logentry->logfile, "(%s) %s %s - %s\n", log_fmttime, loglevels[level - 1], scope > 0 ? segv_inmodule : "CORE", log_buf); + logentry->flush = 1; +#ifndef DEBUG + if (config.foreground) +#endif + printf ("%s %s - %s\n", loglevels[level - 1], scope > 0 ? segv_inmodule : "CORE", log_buf); + } +} + +/** rotate logs, called at midnight + */ +void +reset_logs () +{ + hscan_t hs; + hnode_t *hn; + struct logs_ *logentry; + + SET_SEGV_LOCATION(); + hash_scan_begin (&hs, logs); + while ((hn = hash_scan_next (&hs)) != NULL) { + logentry = hnode_get (hn); + /* If file handle is vald we must have used the log */ + if(logentry->logfile) { + if (logentry->flush > 0) { + fflush (logentry->logfile); + } + fclose (logentry->logfile); + logentry->logfile = NULL; + } + logentry->flush = 0; +#ifdef DEBUG + printf ("Closing Logfile %s (%s)\n", logentry->name, (char *) hnode_getkey (hn)); +#endif + /* make new file name but do not open until needed to avoid 0 length files*/ + make_log_filename(logentry->name, logentry->logname); + } +} + +/* this is for printing out details during an assertion failure */ +void +nassert_fail (const char *expr, const char *file, const int line, const char *infunk) +{ +#ifdef HAVE_BACKTRACE + void *array[50]; + size_t size; + char **strings; + size_t i; +/* thanks to gnulibc libary for letting me find this usefull function */ + size = backtrace (array, 10); + strings = backtrace_symbols (array, size); +#endif + + nlog (LOG_CRITICAL, LOG_CORE, "Assertion Failure!!!!!!!!!!!"); + nlog (LOG_CRITICAL, LOG_CORE, "Function: %s (%s:%d)", infunk, file, line); + nlog (LOG_CRITICAL, LOG_CORE, "Expression: %s", expr); +#ifdef HAVE_BACKTRACE + for (i = 1; i < size; i++) { + nlog (LOG_CRITICAL, LOG_CORE, "BackTrace(%d): %s", i - 1, strings[i]); + } +#endif + nlog (LOG_CRITICAL, LOG_CORE, "Shutting Down!"); + exit (EXIT_FAILURE); +} + diff --git a/log.h b/log.h new file mode 100644 index 0000000..878a1b4 --- /dev/null +++ b/log.h @@ -0,0 +1,105 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + +#ifndef _log_h_ +#define _log_h_ + +/* + * log.h + * dynamic configuration runtime libary + */ + +/* define the log levels */ + +/* critcal crash type notices */ +#define LOG_CRITICAL 1 +/* something is majorly wrong */ +#define LOG_ERROR 2 +/* Hey, you should know about this type messages */ +#define LOG_WARNING 3 +/* did you know messages */ +#define LOG_NOTICE 4 +/* our normal logging level? */ +#define LOG_NORMAL 5 +/* lots of info about what we are doing */ +#define LOG_INFO 6 +/* debug notices about important functions that are going on */ +#define LOG_DEBUG1 7 +/* more debug notices that are usefull */ +#define LOG_DEBUG2 8 +/* even more stuff, that would be useless to most normal people */ +#define LOG_DEBUG3 9 +/* are you insane? */ +#define LOG_DEBUG4 10 + +/* Scope of Logging Defines: */ + +#define LOG_CORE 0 +#define LOG_MOD 1 + +/* buffer size for new customisable filenames + 20 should be more than sufficient */ +#define MAX_LOGFILENAME 20 + +/* this is for the neostats assert replacement. */ +/* Version 2.4 and later of GCC define a magical variable _PRETTY_FUNCTION__' + which contains the name of the function currently being defined. + This is broken in G++ before version 2.6. + C9x has a similar variable called __func__, but prefer the GCC one since + it demangles C++ function names. */ + +#define __NASSERT_FUNCTION __PRETTY_FUNCTION__ +/* Not all compilers provide __STRING so define it here if it is unknown */ +#ifndef __STRING +#define __STRING(x) #x +#endif /* __STRING */ + + +#ifndef __ASSERT_VOID_CAST +#define __ASSERT_VOID_CAST (void) +#endif +extern void nassert_fail (const char *expr, const char *file, const int line, const char *infunk); + +#ifndef NDEBUG +#define nassert(expr) \ + (__ASSERT_VOID_CAST ((expr) ? 0 : \ + (nassert_fail(__STRING(expr), __FILE__, __LINE__, __NASSERT_FUNCTION), 0))) +#else +#define nassert(expr) (__ASSERT_VOID_CAST (0)) +#endif + +extern void nlog (int level, int scope, char *fmt, ...) __attribute__((format(printf,3,4))); /* 2=format 3=params */ +void close_logs (); +int init_logs (); +void reset_logs (); +void fini_logs(); +/* Configurable log filename format string */ +extern char LogFileNameFormat[MAX_LOGFILENAME]; + +#if SQLSRV +void sqlsrvlog(char *logline); +#endif + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..159f677 --- /dev/null +++ b/main.c @@ -0,0 +1,496 @@ +/* MQServer +** Copyright (c) 2004 Justin Hammond +** http://www.dynam.ac/ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** MQServer CVS Identification +** $Id$ +*/ + +#include "config.h" +#include +#include +#ifdef HAVE_BACKTRACE +#include +#endif +#include "defines.h" +#include "signal.h" +#include "conf.h" +#include "log.h" +#include "sock.h" +#include "dotconf.h" + + +/*! Date when we were compiled */ +const char version_date[] = __DATE__; +/*! Time we were compiled */ +const char version_time[] = __TIME__; + +char segv_inmodule[SEGV_INMODULE_BUFSIZE]; +char segv_location[SEGV_LOCATION_BUFSIZE]; +adns_state ads; + +void start (void); +static void setup_signals (void); +static int get_options (int argc, char **argv); +static int init_dns (); + +/*! have we forked */ +int forked = 0; +static int attempts = 0; +jmp_buf sigvbuf; + +/** @brief Main Entry point into program + * + * Sets up defaults, and parses the config file. + * Also initializes different parts of NeoStats + * + * @return Exits the program! + * + * @todo Close STDIN etc correctly + */ +int +main (int argc, char *argv[]) +{ + FILE *fp; + + /* initialise version */ + strncpy(me.version, MQSERVER_VERSION, VERSIONSIZE); + strncpy(me.versionfull, MQSERVER_VERSION, VERSIONSIZE); + + /* get our commandline options */ + if(get_options (argc, argv)!=NS_SUCCESS) + return EXIT_FAILURE; + +#ifndef DEBUG + /* Change to the working Directory */ + if (chdir (NEO_PREFIX) < 0) { + printf ("MQServer Could not change to %s\n", NEO_PREFIX); + printf ("Did you 'make install' after compiling?\n"); + printf ("Error Was: %s\n", strerror (errno)); + return EXIT_FAILURE; + } +#endif + /* before we do anything, make sure logging is setup */ + if(init_logs () != NS_SUCCESS) + return EXIT_FAILURE; + + /* our crash trace variables */ + SET_SEGV_LOCATION(); + CLEAR_SEGV_INMODULE(); + + /* keep quiet if we are told to :) */ + if (!config.quiet) { + printf ("MQServer %s Loading...\n", me.versionfull); + printf ("-----------------------------------------------\n"); + printf ("Copyright 2004\n"); + printf ("Justin Hammond (justin@dynam.ac)\n"); + printf ("-----------------------------------------------\n\n"); + } + /* set some defaults before we parse the config file */ + me.t_start = time(NULL); + me.now = time(NULL); + snprintf (me.strnow, STR_TIME_T_SIZE, "%ld", (long)me.now); + me.die = 0; + me.local[0] = '\0'; +#ifndef DEBUG + me.debug_mode = 0; +#else + me.debug_mode = 1; +#endif + me.r_time = 10; + + /* prepare to catch errors */ + setup_signals (); + + /* init libevent */ + event_init(); + + /* load the config files */ + if(ConfLoad () != NS_SUCCESS) + return EXIT_FAILURE; + + if (me.die) { + printf ("\n-----> ERROR: Read the README file then edit %s! <-----\n\n",CONFIG_NAME); + nlog (LOG_CRITICAL, LOG_CORE, "Read the README file and edit your %s",CONFIG_NAME); + /* we are exiting the parent, not the program, so just return */ + return EXIT_FAILURE; + } + + /* initialize the rest of the subsystems */ + if(init_dns () != NS_SUCCESS) + return EXIT_FAILURE; + + + if (init_client_list() != NS_SUCCESS) + return EXIT_FAILURE; + + +#ifndef DEBUG + /* if we are compiled with debug, or forground switch was specified, DONT FORK */ + if (!config.foreground) { + /* fix the double log message problem by closing logs prior to fork() */ + close_logs(); + forked = fork (); + /* Error check fork() */ + if (forked<0) { + perror("fork"); + return EXIT_FAILURE; /* fork error */ + } +#endif + /* we are the parent */ + if (forked>0) { + /* write out our PID */ + fp = fopen (PID_FILENAME, "w"); + fprintf (fp, "%i", forked); + fclose (fp); + if (!config.quiet) { + printf ("\n"); + printf ("MQServer %s Successfully Launched into Background\n", me.versionfull); + printf ("PID: %i - Wrote to %s\n", forked, PID_FILENAME); + } + return EXIT_SUCCESS; /* parent exits */ + } +#ifndef DEBUG + /* child (daemon) continues */ + /* reopen logs for child */ + if(init_logs () != NS_SUCCESS) + return EXIT_FAILURE; + /* detach from parent process */ + if (setpgid (0, 0) < 0) { + nlog (LOG_WARNING, LOG_CORE, "setpgid() failed"); + } + } +#endif + nlog (LOG_NOTICE, LOG_CORE, "MQServer started (Version %s).", me.versionfull); + /* we are ready to start now Duh! */ + start (); + + /* We should never reach here but the compiler does not realise and may + complain about not all paths control returning values without the return + Since it should never happen, treat as an error condition! */ + return EXIT_FAILURE; +} + +/** @brief Process Commandline Options + * + * Processes commandline options + * + * returns 0 on success, -1 on error +*/ +static int +get_options (int argc, char **argv) +{ + int c; + int dbg; + + SET_SEGV_LOCATION(); + /* set some defaults first */ +#ifdef DEBUG + config.debug = 10; + config.foreground = 1; +#else + config.debug = 5; + config.foreground = 0; +#endif + + while ((c = getopt (argc, argv, "hvrd:nqf")) != -1) { + switch (c) { + case 'h': + printf ("MQServer: Usage: \"neostats [options]\"\n"); + printf (" -h (Show this screen)\n"); + printf (" -v (Show version number)\n"); + printf (" -d 1-10 (Enable debugging output 1= lowest, 10 = highest)\n"); + printf (" -q (Quiet start - for cron scripts)\n"); + printf (" -f (Do not fork into background\n"); + return NS_FAILURE; + case 'v': + printf ("MQServer Version %s\n", me.versionfull); + printf ("Compiled: %s at %s\n", version_date, version_time); + printf ("\nMQServer: http://www.neostats.net\n"); + return NS_FAILURE; + case 'q': + config.quiet = 1; + break; + case 'd': + dbg = atoi (optarg); + if ((dbg > 10) || (dbg < 1)) { + printf ("Invalid Debug Level %d\n", dbg); + return NS_FAILURE; + } + config.debug = dbg; + break; + case 'f': + config.foreground = 1; + break; + default: + printf ("Unknown command line switch %c\n", optopt); + } + } + return NS_SUCCESS; +} + + + +/** @brief Sigterm Signal handler + * + * Called by the signal handler if we get a SIGTERM + * This shutsdown MQServer and exits + * + * @return Exits the program! + * + * @todo Do a nice shutdown, no thtis crap :) + */ +char msg_sigterm[]="SIGTERM received, shutting down server."; + +RETSIGTYPE +serv_die () +{ +#ifdef VALGRIND + exit(NS_SUCCESS); +#else /* VALGRIND */ + nlog (LOG_CRITICAL, LOG_CORE, msg_sigterm); + + do_exit (NS_EXIT_NORMAL, msg_sigterm); +#endif /* VALGRIND */ +} + +/** @brief Sighup Signal handler + * + * Called by the signal handler if we get a SIGHUP + * and rehashes the config file. + * + * @return Nothing + * + * @todo Implement a Rehash function. What can we actually rehash? + */ +RETSIGTYPE +conf_rehash () +{ +/* nothing yet */ +} + + +/** @brief Sigsegv Signal handler + * + * This function is called when we get a SEGV + * and will send some debug into to the logs and to IRC + * to help us track down where the problem occured. + * if the platform we are using supports backtrace + * also print out the backtrace. + * if the segv happened inside a module, try to unload the module + * and continue on our merry way :) + * + * @return Nothing + * + */ +#ifndef HAVE_BACKTRACE +static char backtrace_unavailable[]="Backtrace not available on this platform"; +#endif +static +void do_backtrace(void) +{ +#ifdef HAVE_BACKTRACE + void *array[50]; + size_t size; + char **strings; + int i; + + nlog (LOG_CRITICAL, LOG_CORE, "Backtrace:"); + size = backtrace (array, 10); + strings = backtrace_symbols (array, size); + for (i = 1; i < size; i++) { + nlog (LOG_CRITICAL, LOG_CORE, "BackTrace(%d): %s", i - 1, strings[i]); + } + free (strings); +#else + nlog (LOG_CRITICAL, LOG_CORE, backtrace_unavailable); +#endif +} + +RETSIGTYPE +serv_segv () +{ + /** if the segv happened while we were inside a module, unload and try to restore + * the stack to where we were before we jumped into the module + * and continue on + */ + if (segv_inmodule[0] != 0) { + nlog (LOG_CRITICAL, LOG_CORE, "------------------------SEGFAULT REPORT-------------------------"); + nlog (LOG_CRITICAL, LOG_CORE, "Please view the README for how to submit a bug report"); + nlog (LOG_CRITICAL, LOG_CORE, "and include this segfault report in your submission."); + nlog (LOG_CRITICAL, LOG_CORE, "Module: %s", segv_inmodule); + nlog (LOG_CRITICAL, LOG_CORE, "Location: %s", segv_location); + nlog (LOG_CRITICAL, LOG_CORE, "Unloading Module and restoring stacks. Backtrace:"); + do_backtrace(); + nlog (LOG_CRITICAL, LOG_CORE, "-------------------------END OF REPORT--------------------------"); + /* flush the logs out */ + close_logs(); + longjmp (sigvbuf, -1); + return; + } + /** The segv happened in our core, damn it */ + /* Thanks to Stskeeps and Unreal for this stuff :) */ + /* Broadcast it out! */ + nlog (LOG_CRITICAL, LOG_CORE, "------------------------SEGFAULT REPORT-------------------------"); + nlog (LOG_CRITICAL, LOG_CORE, "Please view the README for how to submit a bug report"); + nlog (LOG_CRITICAL, LOG_CORE, "and include this segfault report in your submission."); + nlog (LOG_CRITICAL, LOG_CORE, "Location: %s", segv_location); + do_backtrace(); + nlog (LOG_CRITICAL, LOG_CORE, "-------------------------END OF REPORT--------------------------"); + close_logs(); + /* clean up */ + do_exit (NS_EXIT_SEGFAULT, NULL); +} + +/** @brief Sets up the signal handlers + * + * Sets up the signal handlers for SIGHUP (rehash) + * SIGTERM (die) and SIGSEGV (segv fault) + * and ignore the others (Such as SIGPIPE) + * + * @return Nothing + * + */ +static void +setup_signals (void) +{ + struct sigaction act; + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + + SET_SEGV_LOCATION(); + /* SIGPIPE/SIGALRM */ + (void) sigemptyset (&act.sa_mask); + (void) sigaddset (&act.sa_mask, SIGPIPE); + (void) sigaddset (&act.sa_mask, SIGALRM); + (void) sigaction (SIGPIPE, &act, NULL); + (void) sigaction (SIGALRM, &act, NULL); + + /* SIGHUP */ + act.sa_handler = conf_rehash; + (void) sigemptyset (&act.sa_mask); + (void) sigaddset (&act.sa_mask, SIGHUP); + (void) sigaction (SIGHUP, &act, NULL); + + /* SIGTERM/SIGINT */ + act.sa_handler = serv_die; + (void) sigaddset (&act.sa_mask, SIGTERM); + (void) sigaction (SIGTERM, &act, NULL); + (void) sigaddset (&act.sa_mask, SIGINT); + (void) sigaction (SIGINT, &act, NULL); + + /* SIGSEGV */ + act.sa_handler = serv_segv; + (void) sigaddset (&act.sa_mask, SIGSEGV); + (void) sigaction (SIGSEGV, &act, NULL); + + (void) signal (SIGHUP, conf_rehash); + (void) signal (SIGTERM, serv_die); + (void) signal (SIGSEGV, serv_segv); + (void) signal (SIGINT, serv_die); +} + +/** @brief before exiting call this function. It flushes log files and tidy's up. + * + * Cleans up before exiting + * @parm segv 1 = we are exiting because of a segv fault, 0, we are not. + * if 1, we don't prompt to save data + */ +void +do_exit (NS_EXIT_TYPE exitcode, char* quitmsg) +{ + /* Initialise exit code to OK */ + int return_code=EXIT_SUCCESS; + SET_SEGV_LOCATION(); + switch (exitcode) { + case NS_EXIT_NORMAL: + nlog (LOG_CRITICAL, LOG_CORE, "Normal shut down subsystems"); + break; + case NS_EXIT_RELOAD: + nlog (LOG_CRITICAL, LOG_CORE, "Reloading MQServer"); + break; + case NS_EXIT_RECONNECT: + nlog (LOG_CRITICAL, LOG_CORE, "Restarting MQServer subsystems"); + break; + case NS_EXIT_ERROR: + nlog (LOG_CRITICAL, LOG_CORE, "Exiting due to error"); + return_code=EXIT_FAILURE; /* exit code to error */ + break; + case NS_EXIT_SEGFAULT: + nlog (LOG_CRITICAL, LOG_CORE, "Shutting down subsystems without saving data due to core"); + return_code=EXIT_FAILURE; /* exit code to error */ + break; + } + + if (exitcode != NS_EXIT_SEGFAULT) { + if (exitcode == NS_EXIT_RECONNECT) { + if(me.r_time>0) { + nlog (LOG_NOTICE, LOG_CORE, "Reconnecting to the server in %d seconds (Attempt %i)", me.r_time, attempts); + sleep (me.r_time); + } + else { + nlog (LOG_NOTICE, LOG_CORE, "Reconnect time is zero, shutting down"); + } + } + + } + + fini_logs(); +#if 0 + if ((exitcode == NS_EXIT_RECONNECT && me.r_time > 0) || exitcode == NS_EXIT_RELOAD) { + execve ("./mqserver", NULL, NULL); + return_code=EXIT_FAILURE; /* exit code to error */ + } +#endif + remove (PID_FILENAME); + exit (return_code); +} + +void fatal_error(char* file, int line, char* func, char* error_text) +{ + SET_SEGV_LOCATION(); + nlog (LOG_CRITICAL, LOG_CORE, "Fatal Error: %s %d %s %s", file, line, func, error_text); + do_exit (NS_EXIT_ERROR, "Fatal Error - check log file"); +} + +/** @brief sets up DNS subsystem + * + * configures ADNS for use with NeoStats. + * + * @return returns 1 on success, 0 on failure +*/ + +int +init_dns () +{ + int adnsstart; + + SET_SEGV_LOCATION(); +#ifndef DEBUG + adnsstart = adns_init (&ads, adns_if_noerrprint | adns_if_noautosys, 0); +#else + adnsstart = adns_init (&ads, adns_if_debug | adns_if_noautosys, 0); +#endif + if (adnsstart) { + printf ("ADNS init failed: %s\n", strerror (adnsstart)); + nlog (LOG_CRITICAL, LOG_CORE, "ADNS init failed: %s", strerror (adnsstart)); + return NS_FAILURE; + } + return NS_SUCCESS; + +} diff --git a/mqserver.cfg b/mqserver.cfg new file mode 100644 index 0000000..86281ae --- /dev/null +++ b/mqserver.cfg @@ -0,0 +1,3 @@ +SERVER_NAME "localhost" +SERVER_PORT 1234 + diff --git a/sock.c b/sock.c new file mode 100644 index 0000000..e416678 --- /dev/null +++ b/sock.c @@ -0,0 +1,286 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** Portions Copyright (c) 1999 Johnathan George net@lite.net +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + +#include +#include +#include +#include +#include + +#include "defines.h" +#include "adns.h" +#include "conf.h" +#include "log.h" +#include "dotconf.h" +#include "client.h" + +static struct sockaddr_in lsa; +static int dobind; + +int servsock; + +static int listen_on_port(int port); + + + + +/** @brief Connect to a server + * + * also setups the SQL listen socket if defined + * + * @param host to connect to + * @param port on remote host to connect to + * + * @return socket connected to on success + * NS_FAILURE on failure + */ +int +ConnectTo (char *host, int port) +{ + int ret; + struct hostent *hp; + struct sockaddr_in sa; + int s; + + SET_SEGV_LOCATION(); + dobind = 0; + /* bind to a local ip */ + memset (&lsa, 0, sizeof (lsa)); + if (me.local[0] != 0) { + if ((hp = gethostbyname (me.local)) == NULL) { + nlog (LOG_WARNING, LOG_CORE, "Warning, Couldn't bind to IP address %s", me.local); + } else { + memcpy ((char *) &lsa.sin_addr, hp->h_addr, hp->h_length); + lsa.sin_family = hp->h_addrtype; + dobind = 1; + } + } + if ((hp = gethostbyname (host)) == NULL) { + return NS_FAILURE; + } + + if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + free(hp); + return NS_FAILURE; + } + if (dobind > 0) { + if (bind (s, (struct sockaddr *) &lsa, sizeof (lsa)) < 0) { + nlog (LOG_WARNING, LOG_CORE, "bind(): Warning, Couldn't bind to IP address %s", strerror (errno)); + } + } + + bzero (&sa, sizeof (sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons (port); + bcopy (hp->h_addr, (char *) &sa.sin_addr, hp->h_length); + + ret=connect (s, (struct sockaddr *) &sa, sizeof (sa)); + if (ret< 0) { + close (s); + return NS_FAILURE; + } + return s; +} + +void client_activity(int fd, short eventtype, void *arg) { + char buf[BUFSIZE]; + mqclient *mqc = arg; + int i; + SET_SEGV_LOCATION(); + if (eventtype == EV_READ) { + bzero(buf, BUFSIZE); + i = read(fd, buf, BUFSIZE); + if (i < 1) { + /* error */ + nlog(LOG_WARNING, LOG_CORE, "Read Error on %d: %s", fd, strerror(errno)); + /* delete sock */ + event_del(&mqc->ev); + del_client(mqc); + close(fd); + return; + } else { + printf("%s", buf); + fflush(NULL); + + } + } +} + + + +void listen_accept(int fd, short eventtype, void *arg) { + unsigned int al; + struct sockaddr_in client_address; + int l; + mqclient *mqc; + SET_SEGV_LOCATION(); + memset (&client_address, 0, al = sizeof (client_address)); + l = accept (fd, (struct sockaddr *)&client_address, &al); + if (l < 0) { + nlog(LOG_WARNING, LOG_CORE, "Accept Failed on %d: %s", fd, strerror(errno)); + return; + } + mqc = new_client(l); + MQC_SET_STAT_CONNECT(mqc); + mqc->ip = client_address; + strncpy(mqc->host, inet_ntoa(client_address.sin_addr), MAXHOST); + nlog(LOG_DEBUG1, LOG_CORE, "New Connection from %s on fd %d", mqc->host, mqc->fd); + event_set(&mqc->ev, l, EV_READ|EV_PERSIST, client_activity, mqc); + event_add(&mqc->ev, NULL); +} + + + +/** @brief main recv loop + * + * @param none + * + * @return none + */ +void +start () +{ + int servsock; + struct event ev; + + SET_SEGV_LOCATION(); + servsock = listen_on_port(me.port); + if (servsock < 0) { + do_exit(NS_EXIT_ERROR, "Can't Create Client Port"); + return; + } + event_set(&ev, servsock, EV_READ|EV_PERSIST, listen_accept, NULL); + event_add(&ev, NULL); + nlog(LOG_NOTICE, LOG_CORE, "Listening for new connections on port %d: (%d)", me.port, servsock); + + while (1) { + SET_SEGV_LOCATION(); + event_loop(EVLOOP_ONCE); + if (me.die) { + do_exit(NS_EXIT_NORMAL, "Normal Exit"); + } + } + + do_exit(NS_EXIT_ERROR, "Exit from Loop"); +} + + + +/** @brief get max available sockets + * + * @param none + * + * @return returns the max available socket + */ +int +getmaxsock () +{ + struct rlimit *lim; + int ret; + + SET_SEGV_LOCATION(); + lim = malloc (sizeof (struct rlimit)); + getrlimit (RLIMIT_NOFILE, lim); + ret = lim->rlim_max; + free (lim); + return ret; +} + +/** @brief send to socket + * + * @param fmt printf style vaarg list of text to send + * + * @return none + */ +void +sts (const char *buf, const int buflen) +{ + int sent; + + SET_SEGV_LOCATION(); + if (servsock == -1) { + nlog(LOG_WARNING, LOG_CORE, "Not sending to server as we have a invalid socket"); + return; + } + sent = write (servsock, buf, buflen); + if (sent == -1) { + nlog (LOG_CRITICAL, LOG_CORE, "Write error: %s", strerror(errno)); + do_exit (NS_EXIT_ERROR, NULL); + } +} + +/*************************************************************** + * listen_on_port(int port): - Open a socket to listen for + * incoming TCP connections on the port given. Return the file + * descriptor if OK, and -1 on any error. The calling routine + * can handle any error condition. + * + * Input: The interger value of the port number to bind to + * Output: The file descriptor of the socket + * Effects: none + ***************************************************************/ +int +listen_on_port(int port) +{ + int srvfd; /* FD for our listen server socket */ + struct sockaddr_in srvskt; + int adrlen; + int flags; + + SET_SEGV_LOCATION(); + adrlen = sizeof(struct sockaddr_in); + (void) memset((void *) &srvskt, 0, (size_t) adrlen); + srvskt.sin_family = AF_INET; + /* bind to the local IP */ + if (dobind) { + srvskt.sin_addr = lsa.sin_addr; + } else { + srvskt.sin_addr.s_addr = INADDR_ANY; + } + srvskt.sin_port = htons(me.port); + if ((srvfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + nlog(LOG_CRITICAL,LOG_CORE, "SqlSrv: Unable to get socket for port %d.", port); + return -1; + } + flags = fcntl(srvfd, F_GETFL, 0); + flags |= O_NONBLOCK; + (void) fcntl(srvfd, F_SETFL, flags); +// setsockopt(srvfd, SOL_SOCKET, SO_REUSEADDR, (char*) 1, sizeof(1)); + + if (bind(srvfd, (struct sockaddr *) &srvskt, adrlen) < 0) + { + nlog(LOG_CRITICAL, LOG_CORE, "Unable to bind to port %d", port); + return -1; + } + if (listen(srvfd, 1) < 0) + { + nlog(LOG_CRITICAL, LOG_CORE, "Unable to listen on port %d", port); + return -1; + } + return (srvfd);} + diff --git a/sock.h b/sock.h new file mode 100644 index 0000000..d9218b8 --- /dev/null +++ b/sock.h @@ -0,0 +1,37 @@ +/* NeoStats - IRC Statistical Services +** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond +** http://www.neostats.net/ +** +** Portions Copyright (c) 2000-2001 ^Enigma^ +** +** 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 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, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +** USA +** +** NeoStats CVS Identification +** $Id$ +*/ + +#ifndef SOCK_H +#define SOCK_H + +int ConnectTo (char * host, int port); +void read_loop (void); +int getmaxsock (void); +void sts (const char *buf, const int buflen); +void start (void); + +int check_sql_sock(); + +#endif diff --git a/version.h b/version.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/version.h @@ -0,0 +1 @@ +