#!/bin/sh
#
# Configuration script for Services.
#
# IRC Services is copyright (c) 1996-2007 Andrew Church.
#     E-mail: <achurch@achurch.org>
# Parts written by Andrew Kempe and others.
# This program is free but copyrighted software; see the file COPYING for
# details.

###########################################################################

# Temporary directory to use for various things.
CONFTMP=conf-tmp

###########################################################################

# Nifty handy functions.

echo2 () {
    $ECHO2 "$*$ECHO2SUF"	# these are defined later
}

log () {
    echo >&3 "$MODE: $*"
}

run () {
    echo >&3 "$MODE: >>> $*"
    ("$@") >&3 2>&3 </dev/null
    xxres=$?
    if [ $xxres -ne 0 ] ; then
	echo >&3 "$MODE: *** Command failed (exit code $xxres)"
    fi
    return $xxres
}

exists () {			# because some shells don't have test -e
    if [ -f $1 -o -d $1 -o -p $1 -o -c $1 -o -b $1 ] ; then
	return 0
    else
	return 1
    fi
}

grep_q () {
    grep >/dev/null 2>&1 "$@"
}

# Kludge around GNU coreutils stuffiness.

head_is_broken=""
if [ x`echo test | head -1 2>/dev/null` != xtest ] ; then
    head_is_broken=broken
elif [ "x`echo test | head -1 2>&1 >/dev/null`" != x ] ; then
    head_is_broken=broken
fi
HEAD () {
    if test "$head_is_broken" ; then
	count=$1; shift
	head -n`echo x$count | cut -c3-` "$@"
    else
	head "$@"
    fi
}

###########################################################################

# Return the default flags for the given C compiler.

def_cc_flags () {
    GCC=no
    a=`echo "x$1" | cut -c1-4`
    if [ "$a" = "xgcc" -o "x$1" = "xkgcc" ] ; then
	GCC=yes
    elif "$1" --version 2>/dev/null | grep_q '(GCC)' ; then
	GCC=yes
    fi
    if [ $GCC = yes ] ; then
	echo "-O2 -fno-strict-aliasing"
    elif [ "X$1" = "Xicc" ] ; then
	echo "-O0 -wd144,167,556"
    fi
}

###########################################################################

# Test for the presence of a given include file or function.  If the
# variable TEST is non-empty, it contains code to be placed at the end of
# main(), and should return 0 if everything is okay, else 1.
#
# For includes: Pass the include filename as an argument.  The variable
# HAVE_include_name, where "include_name" is the name of the include file
# with letters uppercased and non-alphanumerics replaced by underscores, is
# set to 1 if the include file is present, else 0.
#
# For functions: Pass the return type, function name, and prototype as
# arguments.  The variable HAVE_function, where "function" is the name
# of the function with letters uppercased, is set to 1 if the function is
# available, else 0.
#
# For both: The result code of the function will be 0 (true) if the entity
# is present, else 1 (false).

test_include () {
    include="$1"
    inc2="`echo $include | sed 'y+abcdefghijklmnopqrstuvwxyz/.-+ABCDEFGHIJKLMNOPQRSTUVWXYZ___+'`"
    if [ -f "/usr/include/$include" ] ; then
	eval "HAVE_${inc2}=1"
	log "found $include in /usr/include"
	return 0
    fi
    cat >$CONFTMP/test.c <<EOT
#include <$include>
int main() { return 0; }
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
	eval "HAVE_${inc2}=1"
	log "found $include"
	return 0
    else
	eval "HAVE_${inc2}=0"
	log "didn't find $include"
	return 1
    fi
}

test_function () {
    rettype="$1"
    func="$2"
    proto="$3"
    if [ ! "$rettype" -o ! "$func" ] ; then
	log "test_function: missing parameter(s)"
	return 1
    fi
    if [ ! "$proto" ] ; then
	proto="(...)"
    fi
    func2=`echo $func | tr '[a-z]' '[A-Z]'`
    if [ ! "$TEST" ] ; then
	TEST="return 0;"
    fi
    cat >$CONFTMP/test.c <<EOT
    int main() {
	extern int $func$proto;
	$TEST
    }
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test && (run $CONFTMP/test) 2>&1 ; then
	eval "HAVE_${func2}=1"
	log "found $func"
	return 0
    else
	eval "HAVE_${func2}=0"
	log "didn't find $func"
	return 1
    fi
}

###########################################################################

# If something happens that really shouldn't:

whoa_there () {
    cat <<EOT

*** WHOA THERE! ***

We suddenly couldn't compile using the C compiler we already tested!
The command line we used was:
     $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test
Please try to fix this; if you can't, mail achurch@achurch.org
with information about your system, the output from this script,
and the \`configure.log' file generated by this script.

Configuration aborted.

EOT
    exit 4
}

###########################################################################
###########################################################################

# Start of actual script.

###########################################################################

# Create a temporary directory for our use.

if exists $CONFTMP ; then
    rm -rf $CONFTMP
fi
if mkdir $CONFTMP ; then : ; else
    echo "Failed to create temporary directory!  Exiting."
    exit 2
fi
if chmod u+rwx $CONFTMP ; then : ; else
    echo "Cannot write to temporary directory!  Exiting."
    exit 2
fi

###########################################################################

# Variable initialization.

MY_CONFIG_VERSION=8
CONFIG_VERSION=

PROGRAM=ircservices
PREFIX=
BINDEST=/usr/local/sbin
DATDEST=/usr/local/lib/ircservices

TEST_NT=
INSTALL=
MKDIR=
CP_ALL=

CC=
CC_FLAGS=bonkle
CC_LFLAGS=bonkle
CC_LIBS=bonkle
EXE_SUFFIX=bonkle
NO_VARARG_MACROS=
NO_VA_COPY=
NEED_GCC3_HACK=

CLEAN_COMPILE=y
MEMCHECKS=
SHOWALLOCS=
DUMPCORE=

STATIC_MODULES=
CC_SHARED=
CC_DYN_LFLAGS=
CC_DYN_LIBS=
SYMS_NEED_UNDERSCORES=
RANLIB=

TYPE_INT8=
TYPE_INT16=
TYPE_INT32=
SIZEOF_INT=
SIZEOF_LONG=4
SIZEOF_TIME_T=
MAX_TIME_T=
SIZEOF_GID_T=bonkle
HAVE_SOCKLEN_T=

HAVE_STRINGS_H=
HAVE_SYS_SELECT_H=
HAVE_SYS_SYSPROTO_H=

HAVE_STRERROR=
HAVE_SYS_ERRLIST=0
HAVE_HSTRERROR=

HAVE_SNPRINTF=
BAD_SNPRINTF=
HAVE_STRTOK=
HAVE_STRICMP=
HAVE_STRCASECMP=
HAVE_STRDUP=
HAVE_STRSPN=
HAVE_STRSIGNAL=
HAVE_GETTIMEOFDAY=
HAVE_SETGRENT=
HAVE_SETREGID=
HAVE_UMASK=
HAVE_FORK=
HAVE_GETHOSTBYNAME=
HAVE_GETSETRLIMIT=
MISSING=bonkle

FORCED_GCC_2_96=
WARNED_OLD_GCC=

###########################################################################

# How can we echo something without going to the next line?

ECHO2SUF=''
if [ "`echo -n a ; echo -n b`" = "ab" ] ; then
    ECHO2='echo -n'
elif [ "`echo 'a\c' ; echo 'b\c'`" = "ab" ] ; then
    ECHO2='echo' ; ECHO2SUF='\c'
elif [ "`printf 'a' 2>&1 ; printf 'b' 2>&1`" = "ab" ] ; then
    ECHO2='printf "%s"'
else
    # oh well...
    ECHO2='echo'
fi
export ECHO2 ECHO2SUF

###########################################################################

# Command-line parsing.

OPT_OS2=
OPT_BINDEST=
OPT_DATDEST=
OPT_CLEAN_COMPILE=bonkle
OPT_MEMCHECKS=bonkle
OPT_SHOWALLOCS=bonkle
OPT_DUMPCORE=bonkle
IGNORE_CACHE=
DONT_ASK=
NO_DIR_CHECK=
USE_LOCAL_FUNCS=
NO_USE_LOCAL_FUNCS=
USE_STATIC_MODULES=
USE_DYNAMIC_MODULES=
FORCE_GCC_2_96=

USER_CC=
USER_CC_FLAGS=bonkle
USER_CC_LFLAGS=bonkle
USER_CC_LIBS=

export OPT_OS2 OPT_BINDEST OPT_DATDEST IGNORE_CACHE DONT_ASK NO_DIR_CHECK
export USE_LOCAL_FUNCS NO_USE_LOCAL_FUNCS USE_STATIC_MODULES
export NO_USE_STATIC_MODULES OPT_CLEAN_COMPILE OPT_MEMCHECKS OPT_SHOWALLOCS
export OPT_DUMPCORE FORCE_GCC_2_96
export USER_CC USER_CC_FLAGS USER_CC_LFLAGS USER_CC_LIBS

while [ $# -gt 0 ] ; do
    if echo "$1" | grep_q '^-' ; then
	option=`echo "$1" | cut -c2-`
	shift
	if echo "$option" | grep_q '^-' ; then
	    option=`echo "$option" | cut -c2-`
	    if echo "$option" | grep_q '=' ; then
		value=`echo "$option" | sed 's/^[^=]*=//'`
		option=`echo "$option" | sed 's/=.*$//'`
		set -- "$value" "$@"
	    fi
	fi
	if [ "$option" = "check" ] ; then
	    rm -rf $CONFTMP
	    if [ -f config.cache ] ; then
		CACHEVER=`grep '^CONFIG_VERSION=' config.cache | cut -d= -f2`
		if [ "x$CACHEVER" = "x$MY_CONFIG_VERSION" ] ; then
		    exit 0
		else
		    exit 1
		fi
	    else
		exit 1
	    fi
	elif [ "$option" = "ignore-cache" ] ; then
	    IGNORE_CACHE=bonkle
	elif [ "$option" = "no-dir-check" ] ; then
	    NO_DIR_CHECK=bonkle
	elif [ "$option" = "defaults" ] ; then
	    DONT_ASK=bonkle
	elif [ "$option" = "cc" ] ; then
	    USER_CC="$1"
	    shift
	elif [ "$option" = "cflags" ] ; then
	    USER_CC_FLAGS="$1 -m32"
	    shift
	elif [ "$option" = "lflags" ] ; then
	    USER_CC_LFLAGS="$1"
	    shift
	elif [ "$option" = "libs" ] ; then
	    USER_CC_LIBS="$1"
	    shift
	elif [ "$option" = "os2" ] ; then
	    OPT_OS2=1
	elif [ "$option" = "bindest" ] ; then
	    OPT_BINDEST="$1"
	    shift
	elif [ "$option" = "datdest" ] ; then
	    OPT_DATDEST="$1"
	    shift
	elif [ "$option" = "prefix" ] ; then
	    PREFIX="$1"
	    shift
	elif [ "$option" = "use-local-funcs" ] ; then
	    USE_LOCAL_FUNCS=bonkle
	    NO_USE_LOCAL_FUNCS=
	elif [ "$option" = "no-use-local-funcs" ] ; then
	    USE_LOCAL_FUNCS=
	    NO_USE_LOCAL_FUNCS=bonkle
	elif [ "$option" = "use-static-modules" ] ; then
	    USE_DYNAMIC_MODULES=
	    USE_STATIC_MODULES=bonkle
	elif [ "$option" = "no-use-static-modules" ] ; then
	    USE_DYNAMIC_MODULES=bonkle
	    USE_STATIC_MODULES=
	elif [ "$option" = "clean-compile" ] ; then
	    OPT_CLEAN_COMPILE=y
	elif [ "$option" = "no-clean-compile" ] ; then
	    OPT_CLEAN_COMPILE=
	elif [ "$option" = "memchecks" ] ; then
	    OPT_MEMCHECKS=y
	elif [ "$option" = "no-memchecks" ] ; then
	    OPT_MEMCHECKS=
	elif [ "$option" = "showallocs" ] ; then
	    OPT_SHOWALLOCS=y
	elif [ "$option" = "no-showallocs" ] ; then
	    OPT_SHOWALLOCS=
	elif [ "$option" = "dumpcore" ] ; then
	    OPT_DUMPCORE=y
	elif [ "$option" = "no-dumpcore" ] ; then
	    OPT_DUMPCORE=
	elif [ "$option" = "force-gcc-2.96" ] ; then
	    FORCE_GCC_2_96=y
	else
	    if [ "$option" != "help" -a "$option" != "h" ]; then
		echo >&2 Unknown option/parameter: "$option"
		exitval=1
	    else
		exitval=0
	    fi
	    cat >&2 <<EOT

Available options:

  *** Controlling the configure script ***

        -help
        -ignore-cache        Don't use cache file if it exists
        -no-dir-check        Don't check for existence of install directories
        -defaults            Use defaults for all interactive questions
                                (non-interactive configuration)

  *** Controlling compilation ***

        -cc PROGRAM          Specify C compiler to use (overrides cache and
                                check; also clears cached CFLAGS/LFLAGS values)
        -cflags FLAGS        Specify compilation flags (overrides cache/check)
        -lflags FLAGS        Specify link flags for C compiler (default: none)
        -libs LIBS           Specify extra libraries to use (default: none)
        -os2                 Indicate that this is an OS/2 system

  *** Controlling installation ***

  Note that the script will not create any directories specified with these
  options; if the directorires do not exist when "make install" is executed,
  the installation will fail.

        -bindest DIR         Specify directory for program file installation
        -datdest DIR         Specify directory for data file installation
        -prefix DIR          Specify GNU-style installation prefix (program
                                will be installed in DIR/sbin, data in
                                DIR/lib/services); overrides -bindest/-datdest

  *** Controlling Services features ***

  Note that the following functions can be disabled by adding "no-" before
  the option name; for example, "-no-use-local-funcs".  For options with a
  * before the option name, the option is on by default, and you must
  explicitly give -no-option-name to disable it.

        -use-local-funcs     Force the use of compatibility functions over
                                system library functions (for debugging)
        -use-static-modules  Force modules to be compiled statically, even if
                                dynamic modules could be used
      * -clean-compile       Attempt to compile with no warnings (causes a
                                slight performance penalty)
        -memchecks           Perform extra checks on memory allocation (for
                                debugging only; causes a significant
                                performance penalty)
        -showallocs          Log all memory allocation activity (for
                                debugging only; ignored unless -memchecks
                                is enabled)
        -dumpcore            Causes Services to attempt to write a core
                                file if it crashes (for debugging)

   *** Other options ***

        -force-gcc-2.96      Allow use of GCC 2.96 (unsupported).  See
                                question B.1 in the FAQ for details.
        -check               Check whether this script has already been run
                                and whether the cache is up-to-date.  Exits
                                with 0 if up-to-date, 1 if not.


GNU-style long options (--option[=value]) may also be used.

Note that environment variables such as CC and CFLAGS are ignored; use
the corresponding command-line options (-cc, -cflags, etc.) instead.
EOT
	    exit $exitval
	fi
    fi
done

###########################################################################

echo ""
echo "Beginning IRC Services configuration."
echo ""

###########################################################################

# First, test for the presence of a config.cache file.  If found, either
# don't use it (-ignore-cache), or let the user know how to not use it and
# then use it.

if [ -f config.cache -a -r config.cache -a ! "$IGNORE_CACHE" ] ; then
    cat <<EOT
Using defaults from config.cache.  To ignore, either remove config.cache or
give the command-line option "-ignore-cache".

EOT
    . ./config.cache
    # Clear list of missing functions if either a relevant HAVE_* variable
    # is missing or -no-use-local-funcs was specified.
    if [ "$NO_USE_LOCAL_FUNCS" \
		-o ! "$HAVE_SNPRINTF" \
		-o ! "$BAD_SNPRINTF" \
		-o ! "$HAVE_STRTOK" \
		-o ! "$HAVE_STRICMP" \
		-o ! "$HAVE_STRCASECMP" \
		-o ! "$HAVE_STRDUP" \
		-o ! "$HAVE_STRSPN" \
		-o ! "$HAVE_STRSIGNAL" \
		-o ! "$HAVE_GETTIMEOFDAY" \
		-o ! "$HAVE_SETGRENT" \
		-o ! "$HAVE_SETREGID" \
		-o ! "$HAVE_UMASK" \
		-o ! "$HAVE_FORK" \
		-o ! "$HAVE_GETHOSTBYNAME" \
		-o ! "$HAVE_GETSETRLIMIT" \
    ] ; then
	MISSING=bonkle
    fi
    if [ ! "$CONFIG_VERSION" ] ; then
	CONFIG_VERSION=0
	CC_LFLAGS=bonkle
	CC_LIBS=bonkle
    fi
    if [ $CONFIG_VERSION -lt 2 ] ; then
	# missing -fno-strict-aliasing
	CC=
	CC_FLAGS=bonkle
    fi
    if [ $CONFIG_VERSION -lt 4 ] ; then
	# socklen_t test broken on FreeBSD
	HAVE_SOCKLEN_T=
    fi
    if [ $CONFIG_VERSION -lt 6 ] ; then
	# deprecated GCC < 3.2, so recheck compiler
	CC=
    fi
    if [ $CONFIG_VERSION -lt 7 ] ; then
	# Added -fstack-protector avoidance, so recheck compiler flags
	CC=
    fi
    if [ $CONFIG_VERSION -lt 8 ] ; then
	# Added __builtin_xxx() bug check and fixed -fstack-protector
	# avoidance, so recheck compiler and flags
	CC=
    fi
    if [ "$USE_DYNAMIC_MODULES" ] ; then
	STATIC_MODULES=
	RANLIB=
    fi
    if [ "$USE_STATIC_MODULES" ] ; then
	RANLIB=
    fi
    if [ "x$USER_CC" != "x" -o "x$CC" = "x" ] ; then
	# don't mix old flags and new compiler
	CC_FLAGS=bonkle
	CC_LFLAGS=bonkle
    fi
fi

if [ "$OPT_CLEAN_COMPILE" != bonkle ] ; then
    CLEAN_COMPILE=$OPT_CLEAN_COMPILE
fi
if [ "$OPT_MEMCHECKS" != bonkle ] ; then
    MEMCHECKS=$OPT_MEMCHECKS
fi
if [ "$OPT_SHOWALLOCS" != bonkle ] ; then
    SHOWALLOCS=$OPT_SHOWALLOCS
fi
if [ "$OPT_DUMPCORE" != bonkle ] ; then
    DUMPCORE=$OPT_DUMPCORE
fi

if [ "$FORCED_GCC_2_96" ] ; then
    # Clear the cache and check again (and print the warning again)
    CC=
fi

###########################################################################

# Ask the user anything we need to know ahead of time.

default=0

if [ "$PREFIX" ] ; then
    OPT_BINDEST="$PREFIX/sbin"
    OPT_DATDEST="$PREFIX/lib/services"
elif [ "$DONT_ASK" ] ; then
    if [ ! "$OPT_BINDEST" ] ; then OPT_BINDEST="$BINDEST" ; default=1 ; fi
    if [ ! "$OPT_DATDEST" ] ; then OPT_DATDEST="$DATDEST" ; fi
fi

####

asked=0
export ok INPUT default asked

####

if [ "$OPT_BINDEST" ] ; then

    BINDEST="$OPT_BINDEST"
    echo "Executable (program) file will be installed in $BINDEST"
    if exists "$BINDEST/services.h" ; then
	echo "$BINDEST appears to contain a Services source code distribution; aborting."
	exit 1
    fi

else

    ok=0
    asked=1
    echo "In what directory do you want the binaries to be installed?"
    echo "Press Return for the default, or enter a new value."
    while [ $ok -eq 0 ] ; do
	echo2 "[$BINDEST] "
	if read INPUT ; then : ; else echo "" ; exit 1 ; fi
	if [ ! "$INPUT" ] ; then
	    INPUT=$BINDEST
	    default=1
	fi
	if echo "$INPUT" | grep_q \[\'\"\\\] ; then
	    echo 'Please use a pathname without the characters: '\'' " \'
	elif [ ! "$NO_DIR_CHECK" -a ! -d "$INPUT" ] ; then
	    if exists "$INPUT" ; then
		echo "$INPUT exists, but is not a directory!"
	    else
		echo "$INPUT does not exist.  Create it?"
		echo2 "[y] "
		read YN
		if [ "$YN" != "n" ] ; then
		    if mkdir -p "$INPUT" ; then
			ok=1
		    fi
		fi
	    fi
	elif exists "$INPUT/services.h" ; then
	    echo "You cannot use the Services source directory as a target directory."
	else
	    ok=1
	fi
    done
    BINDEST=$INPUT
    echo ""

fi

####

if [ "$OPT_DATDEST" ] ; then

    DATDEST="$OPT_DATDEST"
    echo "Data files will be installed in $DATDEST"
    if exists "$DATDEST/services.h" ; then
	echo "$DATDEST appears to contain a Services source code distribution; aborting."
	exit 1
    fi

else

    if [ ! "$DATDEST" -o $default -eq 0 ] ; then
	if [ x`echo "$BINDEST" | grep -c '/\(sbin\|bin\)$'` = x1 ] ; then
	    DATDEST=`echo "$BINDEST" | sed 's,\(sbin\|bin\)$,lib/ircservices,'`
	else
	    DATDEST=`echo "$BINDEST" | sed s,/*$,,`/lib
	fi
    fi
    ok=0
    asked=1
    echo "Where do you want the data files to be installed?"
    while [ $ok -eq 0 ] ; do
	echo2 "[$DATDEST] "
	if read INPUT ; then : ; else echo "" ; exit 1 ; fi
	if [ ! "$INPUT" ] ; then
	    INPUT=$DATDEST
	fi
	if echo "$INPUT" | grep_q \[\'\"\\\] ; then
	    echo 'Please use a pathname without the characters: '\'' " \'
	elif [ ! "$NO_DIR_CHECK" -a ! -d "$INPUT" ] ; then
	    if exists "$INPUT" ; then
		echo "$INPUT exists, but is not a directory!"
	    else
		echo "$INPUT does not exist.  Create it?"
		echo2 "[y] "
		read YN
		if [ "$YN" != "n" ] ; then
		    if mkdir -p "$INPUT" ; then
			ok=1
		    fi
		fi
	    fi
	elif exists "$INPUT/services.h" ; then
	    echo "You cannot use the Services source directory as a target directory."
	else
	    ok=1
	fi
    done
    DATDEST=$INPUT
    echo ""

fi

####

if [ $asked != 0 ] ; then
    echo "End of interactive configuration."
    echo ""
fi

###########################################################################

# Set up log file for automated tests, so we have a clue what's going on if
# something dies.

exec 3>configure.log

MODE="                   "
TEST=""
export MODE TEST

###########################################################################

# Check whether we have a working "test FILE_A -nt FILE_B".

MODE="check_test_nt      "
if [ "$TEST_NT" ] ; then
    log "cache says $TEST_NT"
else
    echo2 "Checking sanity of /bin/sh... "
    touch $CONFTMP/file1
    sleep 2  # just in case sleep 1 really does a sleep 0.997 or some such
    touch $CONFTMP/file2
    if run /bin/sh -c "test $CONFTMP/file2 -nt $CONFTMP/file1" ; then
	TEST_NT=test
	log "test works"
	echo "high."
    elif run /bin/test $CONFTMP/file2 -nt $CONFTMP/file1 ; then
	TEST_NT=/bin/test
	log "/bin/test works"
	echo "medium."
    elif run /usr/bin/test $CONFTMP/file2 -nt $CONFTMP/file1 ; then
	TEST_NT=/usr/bin/test
	log "/usr/bin/test works"
	echo "medium."
    else
	log "neither test nor /bin/test nor /usr/bin/test work!"
	echo "low."
	echo "    Warning: Compilation may fail unless you pass a saner shell to make:"
	echo "             make [or gmake] SHELL=/usr/local/bin/bash ..."
    fi
fi

###########################################################################

# Search for a compiler.

MODE="find_cc            "
# Don't use the cached flags unless we use the cached compiler as well
CACHED_CC_FLAGS=$CC_FLAGS -m32
CC_FLAGS=bonkle
echo2 "Searching for a suitable compiler... "
if [ "$USER_CC" ] ; then
    CC="$USER_CC"
    if $CC --version 2>&1 | fgrep 2.96 >/dev/null ; then
	log user supplied \`"$CC'", which appears to be GCC 2.96
	log output of \`"$CC --version':"
	run $CC --version
	cat <<EOT


*** WHOA THERE! ***

The C compiler you specified, \`$CC', seems to be GCC 2.96.
This is an unofficial release of the GCC compiler which
contains serious bugs and cannot compile Services correctly.

EOT
	if [ "$FORCE_GCC_2_96" ] ; then
	    cat <<EOT
-force-gcc-2.96 was specified, so configuration will continue
anyway.  However, be aware that the author of Services will not
support any installation of Services compiled with GCC 2.96.

See question B.1 in the FAQ for details.

EOT
	    echo2 "Press Enter to continue: ";
	    read dummy
	    log 'using it anyway (forced)'
	    FORCE_GCC_2_96=forced
	    CC=gcc
	    DEF_CC_FLAGS="-O2 -m32 -fno-strict-aliasing"
	else
	    cat <<EOT
Please upgrade GCC to a newer version before compiling Services.

See question B.1 in the FAQ for details.

EOT
	    log 'aborting'
	    exit 1
	fi
    else
	echo "(supplied) using $CC."
	log user supplied \`"$CC'"
	DEF_CC_FLAGS=`def_cc_flags $CC -m32`
    fi
elif [ "$CC" ] ; then
    echo "(cached) using $CC."
    log cache supplied \`"$CC'"
    CC_FLAGS=$CACHED_CC_FLAGS
elif run gcc --version ; then
    version=`gcc --version 2>&1 | HEAD -1 | sed 's/[^0-9]*[^0-9.]\([0-9][0-9.]*\).*/\1/'`
    vmajor=`echo "x.$version.0" | cut -d. -f2`
    vminor=`echo "x.$version.0" | cut -d. -f3`
    if test "x$version" = x || (echo "x$vmajor" | cut -c2- | grep '[^0-9]' >/dev/null 2>&1) || (echo "x$vminor" | cut -c2- | grep '[^0-9]' >/dev/null 2>&1) ; then
	log "unparseable version string: $version"
	cat <<EOT


*** WHOA THERE! ***

Unable to determine the version of GCC installed on your system.  Please
make certain you are using an official GCC distribution.  If you are
certain \`gcc' is the correct compiler on your system and it is a recent
version of GCC, re-run this script with the option \`-cc gcc' (or
\`--cc=gcc').

Configuration aborted.

EOT
	exit 1
    fi
    if [ $vmajor = 2 -a $vminor = 96 ] ; then
	cat <<EOT


*** WHOA THERE! ***

Your system seems to have gcc 2.96 installed.
This is an unofficial release of the GCC compiler which contains serious
bugs and cannot compile Services correctly.

EOT
	log 'found gcc 2.96'
	OTHER_GCC=
	if run gcc3 --version ; then
	    cat <<EOT
\`gcc3' is available on this system and may work, so we'll use it
instead.  However, you should be aware that GCC 2.96 can cause problems
with compiling other programs as well; you should consider removing it.

See question B.1 in the FAQ for details.

EOT
	    echo2 "Press Enter to continue: ";
	    read dummy
	    log using \`gcc3\'
	    CC=gcc3
	    DEF_GCC_FLAGS="-O2 -m32 -fno-strict-aliasing"
	elif run kgcc --version ; then
	    cat <<EOT
\`kgcc' is available on this system and may work, but you should strongly
consider upgrading GCC to a newer version.  If you experience any
problems compiling or using Services, please upgrade GCC before sending
in a bug report.

See question B.1 in the FAQ for details.

EOT
	    echo2 "Press Enter to continue: ";
	    read dummy
	    log using \`kgcc\'
	    CC=kgcc
	    DEF_GCC_FLAGS="-O2 -m32 -fno-strict-aliasing"
	elif [ "$FORCE_GCC_2_96" ] ; then
	    cat <<EOT
-force-gcc-2.96 was specified, so configuration will continue anyway.
However, be aware that the author of Services will not support any
installation of Services compiled with GCC 2.96.

See question B.1 in the FAQ for details.

EOT
	    echo2 "Press Enter to continue: ";
	    read dummy
	    log 'using `gcc'\'' (forced)'
	    FORCE_GCC_2_96=forced
	    CC=gcc
	    DEF_CC_FLAGS="-O2 -m32 -fno-strict-aliasing"
	else
	    cat <<EOT
Please upgrade GCC to a newer version before compiling Services.  See
question B.1 in the FAQ for details.

Configuration aborted.

EOT
	    log 'gcc3/kgcc not found, aborting'
	    exit 1
	fi
    else
	if test $vmajor -lt 3 -a $version != 2.95.3 || test $vmajor = 3 -a $vminor -lt 2 ; then
	    cat <<EOT

WARNING: Your version of GCC was detected as \`$version'.  As of Services
         5.0.23, versions of GCC earlier than 3.2, other than 2.95.3,
         have been deprecated.  This and future releases of Services 5.0
         will still work, though some error messages will lose
         information; future versions of Services may not compile at
         all.  Please upgrade your compiler to GCC 3.2 or later.

EOT
	    echo2 "Press Enter to continue: "
	    read dummy
	    WARNED_OLD_GCC=1
	    log using \`gcc\' \(bad version: $version\)
	else  # version okay
	    echo "great, found gcc!"
	    log using \`gcc\'
	fi
	CC=gcc
	DEF_CC_FLAGS=`def_cc_flags $CC -m32`
    fi
else
    echo "gcc not found."
    echo2 "    Looking for alternatives... "
    echo >$CONFTMP/test.c "int main(){return 1;}"
    if run icc $CONFTMP/test.c -o $CONFTMP/test ; then
	CC=icc
    elif run cc $CONFTMP/test.c -o $CONFTMP/test ; then
	CC=cc
    elif run c89 $CONFTMP/test.c -o $CONFTMP/test ; then
	CC=c89
    else
	echo "no C compiler found!"
	echo "    Use the -cc command line option to specify your C compiler."
	log "automatic tests failed"
	exit 2
    fi
    # See if it handles ANSI.
    cat >$CONFTMP/test.c <<EOT
    int main(int argc, char **argv) {
	extern void foo(int bar);
    }
EOT
    log "test for ANSI..."
    if run $CC $CONFTMP/test.c -o $CONFTMP/test ; then
	echo "using $CC."
	DEF_CC_FLAGS=`def_cc_flags $CC -m32`
	if [ "x$DEF_CC_FLAGS" = "x" -a "x$USER_CC_FLAGS" = "x" ] ; then
	    echo "    Defaulting to no compiler flags.  Use the -cflags option"
	    echo "    if you need to specify any."
	fi
	log using \`"$CC'"
    else
	echo "found $CC, but it's not ANSI-compliant!"
	echo "    Use the -cc command line option to specify your C compiler."
	log \`"$CC' not ANSI-compliant"
	exit 2
    fi
fi


# See whether compiler supports various C99 features.

log "test vararg macros..."
cat >$CONFTMP/test.c <<EOT
#define foo(a,...) int a() {printf("hello %s\n" , ##__VA_ARGS__); return 69;}
foo(main,"world")
EOT
if run $CC $CONFTMP/test.c -o $CONFTMP/test && (run $CONFTMP/test; test $? = 69) ; then
    log "vararg macros ok."
    NO_VARARG_MACROS=
else
    log "vararg macros NG!"
    if [ ! "$WARNED_OLD_GCC" ] ; then
	cat <<EOT

WARNING: Your C compiler is not compliant with modern C standards.
         Services 5.0 will still compile, but some features may be
         unavailable or degraded; future versions of Services may not
         compile correctly at all.  Please upgrade your compiler to one
         that supports the C99 standard (such as GCC 3.2 and later).
         See section 2-1 of the manual for details.

EOT
	echo2 "Press Enter to continue: "
	read dummy
	WARNED_OLD_GCC=1
    fi
    NO_VARARG_MACROS=1
fi

log "test va_copy..."
cat >$CONFTMP/test.c <<EOT
#include <stdarg.h>
void foo(int a,...) {
    va_list args, args2;
    va_start(args,a);
    va_copy(args2, args);
    va_end(args);
    va_end(args2);
}
int main() {
    foo(1,2);
    return 0;
}
EOT
if run $CC $CONFTMP/test.c -o $CONFTMP/test && run $CONFTMP/test ; then
    log "va_copy ok."
    NO_VA_COPY=
else
    log "va_copy NG!"
    if [ ! "$WARNED_OLD_GCC" ] ; then
	cat <<EOT

WARNING: Your C compiler is not compliant with modern C standards.
         Services 5.0 will still compile, but some features may be
         unavailable or degraded; future versions of Services may not
         compile correctly at all.  Please upgrade your compiler to one
         that supports the C99 standard (such as GCC 3.2 and later).
         See section 2-1 of the manual for details.

EOT
	echo2 "Press Enter to continue: "
	read dummy
	WARNED_OLD_GCC=1
    fi
    NO_VA_COPY=1
fi


# Test compiler options.

MODE="find_ccopts        "
if [ "$USER_CC_FLAGS" != bonkle ] ; then
    CC_FLAGS="$USER_CC_FLAGS"
    echo "Compiler flags supplied: $CC_FLAGS"
    log user supplied flags: \`"$CC_FLAGS'"
elif [ "$CC_FLAGS" != bonkle ] ; then
    echo "Compiler flags: (cached) $CC_FLAGS"
    log cache supplied flags: \`"$CC_FLAGS'"
else

    CC_FLAGS=$DEF_CC_FLAGS

    # Test for GCC stack-protector patch (generates broken code).
    log "check for SSP"
    cat >$CONFTMP/test.c <<EOT
	void bar(int hogehoge) { printf("%d", hogehoge); }
	void foo(int xyzzy) { __builtin_apply(bar,__builtin_apply_args(),64); }
	int main(int ac, char **av) { foo(ac>1 ? 24 : 42); return 0; }
EOT
    if run $CC $CC_FLAGS -fstack-protector $CONFTMP/test.c -o $CONFTMP/test
    then
	log "SSP present"
	# See if the bug exists; if so, disable stack protection.  Test
	# twice just in case the bug exists but the stack happens to
	# randomly contain 42.
	a=`$CONFTMP/test`
	b=`$CONFTMP/test x`
	log "test results: a=[$a] b=[$b]"
	if [ "$a" != 42 -o "$b" != 24 ] ; then
	    CC_FLAGS="$CC_FLAGS -fno-stack-protector"
	    log "SSP bug found, disabling"
	else
	    log "SSP bug not detected"
	fi
    else
	log "SSP not present"
    fi

    echo2 "Testing default compiler flags ($CC_FLAGS)... "
    cat >$CONFTMP/test.c <<EOT
	int main(int argc, char **argv) {
	    extern void foo(int bar);
	}
EOT
    if run $CC $CC_FLAGS -c $CONFTMP/test.c -o $CONFTMP/test.o ; then
	echo "looks good."
    else
	echo "no luck!  Using no flags."
	echo "    If you know what flags you want, use the -cflags option to configure."
	CC_FLAGS=
    fi
    log using flags: \`"$CC_FLAGS'"
fi
# If -fstack-protector isn't disabled, test once more to make sure
# __builtin_apply() is working--but watch out for the __builtin_apply()
# bugs below, as well as http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20076
if ! echo "$CC_FLAGS" | grep_q fno-stack-protector ; then
    log "-fstack-protector check"
    cat >$CONFTMP/test.c <<EOT
#if defined(__sparc__)
# define APPLY __builtin_apply(bar,__builtin_apply_args(),64); asm("ld [%sp-128],%i0")
#elif defined(__POWERPC__)
# define APPLY __builtin_apply(bar,__builtin_apply_args(),64); asm("mr r0,r3")
#else
# define APPLY __builtin_return(__builtin_apply(bar,__builtin_apply_args(),64))
#endif
	int bar(int hogehoge) { return printf("%d", hogehoge); }
	int foo(int xyzzy) { APPLY; }
	int main(int ac, char **av) { printf(" %d",foo(ac>1?9:42)); return 0; }
EOT
    if run $CC $CC_FLAGS -fno-inline-functions $CONFTMP/test.c -o $CONFTMP/test
    then
	run $CONFTMP/test  # to get the output into the log file
	a=`$CONFTMP/test`
	b=`$CONFTMP/test x`
	log "test results: a=[$a] b=[$b]"
	if [ "$a" != "42 2" -o "$b" != "9 1" ] ; then
	    log "-fstack-protector check failed!"
	    cat <<EOT

*** WHOA THERE! ***

Your compiler is not compiling certain code correctly; this will result in
crashes when running Services.  If you have specified compiler flags, please
add "-fno-stack-protector" to the flags, or remove "-fstack-protector" if it
is present.  If this does not help, please reinstall or upgrade your
compiler.  See section 2-1 of the manual for details.

Configuration aborted.

EOT
	    exit 1
	fi
    else
	# For whatever reason, the compilation failed; maybe the compiler
	# isn't a GCC flavor and doesn't understand -fno-inline-functions
	# or __builtin_apply().  Assume things are okay.
	log "-fstack-protector check compilation failed, ignoring"
    fi
fi

###########################################################################

# Check for the GCC __builtin_apply() and __builtin_return() bugs:
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8028
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11151

MODE="check_gcc_builtin  "

# Check whether this is actually GCC--if it doesn't understand
# __builtin_apply, then probably not.
cat >$CONFTMP/test.c <<EOT
    int foo(int n)
    {
	return n;
    }

    int bar(int n)
    {
	return n*n+1;
    }

    int quux(int n)
    {
	foo(0);
	__builtin_return(__builtin_apply((void *)bar, __builtin_apply_args(), 64));
    }

    int main(int argc, char **argv)
    {
	return quux(2)==5 && quux(3)==10 ? 0 : 1;
    }
EOT
# As with the SSP check, avoid Bugzilla bug 20076 with -fno-inline-functions
if run $CC $CC_FLAGS -fno-inline-functions $CONFTMP/test.c -o $CONFTMP/test ; then
    log "checking for __builtin_apply()/__builtin_return() bugs"
    # See if it runs correctly.
    if run $CONFTMP/test ; then
	log "bugs not detected"
    else
	case `uname -m` in
	    i?86|sparc|powerpc|"Power Macintosh")
		log "bugs detected, applying workaround"
		NEED_GCC3_HACK=y
		;;
	    *)
		cat <<EOT

*** WHOA THERE! ***

Your C compiler has a bug which causes Services to be compiled incorrectly,
and no workaround is available for your hardware.  Please try upgrading
your compiler to the most recent version available (if you are using GCC,
check http://gcc.gnu.org/ for the latest version).  See FAQ B.1.5 for
details.

Configuration aborted.

EOT
		exit 1
		;;
	esac
    fi
fi

###########################################################################

# Set linker flags.

MODE="find_lflags        "
if [ "$USER_CC_LFLAGS" != "bonkle" ] ; then
    CC_LFLAGS=$USER_CC_LFLAGS
    log user supplied \`"$CC_LFLAGS'"
elif [ "$CC_LFLAGS" != "bonkle" ] ; then
    log cache supplied \`"$CC_LFLAGS'"
else
    log using none
    CC_LFLAGS=""
fi

###########################################################################

# Find executable suffix.

MODE="find_exe_suffix    "
if [ "$OPT_OS2" ] ; then
    log "-os2 option given, using \`.exe'"
    EXE_SUFFIX=.exe
else
    rm -f $CONFTMP/test $CONFTMP/test.exe
    echo >$CONFTMP/test.c "int main(){return 1;}"
    if run $CC $CC_FLAGS $CC_LFLAGS $CONFTMP/test.c -o $CONFTMP/test ; then
	if [ -f $CONFTMP/test.exe ] ; then
	    log using .exe
	    EXE_SUFFIX=.exe
	elif [ -f $CONFTMP/test ] ; then
	    log using nothing
	    EXE_SUFFIX=""
	else
	    log "can't find executable, assuming nothing"
	    EXE_SUFFIX=
	fi
    else
	log "can't link test program, assuming nothing"
	EXE_SUFFIX=
    fi
fi

###########################################################################

# See what libraries we have that we might need.

MODE="find_libs          "
echo2 "Let's see what libraries we need..."
if [ "$CC_LIBS" != bonkle ] ; then
    if [ "$CC_LIBS" ] ; then
	echo " (cached) $CC_LIBS"
    else
	echo " (cached) none"
    fi
    log cache supplied \`"$CC_LIBS'"
else
    CC_LIBS=
    HAVE_RESOLV=0
    cat >$CONFTMP/test.c <<EOT
	int main(int argc, char **argv) {
	    extern void foo(int bar);
	}
EOT
    cat >$CONFTMP/test-socket.c <<EOT
	int main(int argc, char **argv) {
	    extern void socket();
	    socket();
	}
EOT
    cat >$CONFTMP/test-gethost.c <<EOT
	int main(int argc, char **argv) {
	    extern void gethostbyname();
	    gethostbyname();
	}
EOT
    cat >$CONFTMP/test-hstrerror.c <<EOT
	int main(int argc, char **argv) {
	    extern void hstrerror();
	    hstrerror();
	}
EOT
    if run $CC $CC_FLAGS $CONFTMP/test-socket.c $CC_LIBS -o $CONFTMP/test ; then
	:
    elif run $CC $CC_FLAGS $CONFTMP/test-socket.c $CC_LIBS -lsocket -o $CONFTMP/test ; then
	CC_LIBS="$CC_LIBS -lsocket"
	echo2 " -lsocket"
    fi
    if run $CC $CC_FLAGS $CONFTMP/test-gethost.c $CC_LIBS -o $CONFTMP/test ; then
	:
    elif run $CC $CC_FLAGS $CONFTMP/test-gethost.c $CC_LIBS -lresolv -o $CONFTMP/test ; then
	CC_LIBS="$CC_LIBS -lresolv"
	HAVE_RESOLV=1
	echo2 " -lresolv"
    elif run $CC $CC_FLAGS $CONFTMP/test-gethost.c $CC_LIBS -lnsl -o $CONFTMP/test ; then
	CC_LIBS="$CC_LIBS -lnsl"
	echo2 " -lnsl"
    elif run $CC $CC_FLAGS $CONFTMP/test-gethost.c $CC_LIBS -lnsl -lresolv -o $CONFTMP/test ; then
	CC_LIBS="$CC_LIBS -lnsl -lresolv"
	HAVE_RESOLV=1
	echo2 " -lnsl -lresolv"
    fi
    if [ $HAVE_RESOLV = 0 ] ; then
	if run $CC $CC_FLAGS $CONFTMP/test-hstrerror.c $CC_LIBS -o $CONFTMP/test ; then
	    :
	elif run $CC $CC_FLAGS $CONFTMP/test-hstrerror.c $CC_LIBS -lresolv -o $CONFTMP/test ; then
	    CC_LIBS="$CC_LIBS -lresolv"
	    HAVE_RESOLV=1
	    echo2 " -lresolv"
	fi
    fi
#    if run $CC $CC_FLAGS $CONFTMP/test.c -lbsd -o $CONFTMP/test ; then
#	CC_LIBS="$CC_LIBS -lbsd"
#	echo2 " -lbsd"
#    fi
    echo ""
    CC_LIBS="`echo $CC_LIBS | sed 's/^ +//'`"
fi
if [ "$USER_CC_LIBS" ] ; then
    CC_LIBS="$CC_LIBS $USER_CC_LIBS"
    echo "Additional user-supplied libraries: $USER_CC_LIBS"
    log user added \`"$USER_CC_LIBS'"
fi

###########################################################################

MODE="check_shared       "
if [ "$USE_STATIC_MODULES" ] ; then
    echo "Modules will be compiled statically (-use-static-modules option)."
    STATIC_MODULES=1
    CC_SHARED=
    CC_DYN_LFLAGS=
    CC_DYN_LIBS=
    log "static modules selected (-use-static-modules)"
else
    echo2 "Checking if we can use dynamic modules... "
    if [ "$STATIC_MODULES" = 0 ] ; then
	echo "(cached) yes."
	log "dynamic modules selected (cache)"
    elif [ "$STATIC_MODULES" = 1 ] ; then
	echo "(cached) no."
	log "static modules selected (cache)"
    else
	OK=ok
	dlfcn_ok=0
	if test_include dlfcn.h ; then
	    dlfcn_ok=1
	else
	    log "dlfcn.h not found, skipping dlfcn test"
	fi
	if [ $dlfcn_ok = 1 ] ; then
	    log "testing dlfcn method"
	    cat >$CONFTMP/test-dlopen.c <<EOT
		#include <dlfcn.h>
		int main(int argc, char **argv) {
		    void *lib = dlopen("$CONFTMP/test-lib.so", RTLD_NOW);
		    printf("%d\n", lib != 0);
		    if (lib)
			dlclose(lib);
		    return 0;
		}
EOT
	    cat >$CONFTMP/test-lib.c <<EOT
		int foo() {no_such_symbol();}
EOT
	    if run $CC $CC_FLAGS $CC_LIBS $CONFTMP/test-dlopen.c -o $CONFTMP/test ; then
		CC_DYN_LIBS=""
		log "dlopen() found (no libs)"
	    elif run $CC $CC_FLAGS $CC_LIBS $CONFTMP/test-dlopen.c -ldl -o $CONFTMP/test
	    then
		CC_DYN_LIBS=" -ldl"
		log "dlopen() found (libdl)"
	    else
		log "dlopen() not found"
		OK=
	    fi
	    if [ "$OK" ] ; then
		if run $CC -rdynamic $CC_FLAGS $CC_LIBS $CC_DYN_LIBS $CONFTMP/test-dlopen.c -o $CONFTMP/test ; then
		    log "-rdynamic works"
		    CC_DYN_LFLAGS=" -rdynamic"
		else
		    log "no -rdynamic, aborting dlfcn test"
		    OK=
		fi
	    fi
	    if [ "$OK" ] ; then
	        if [ "x`uname -s`" = "xOSF1" ] ; then
		    CC_SHARED="$CC -shared -m32 -Wl,-expect_unresolved"
		else
		    CC_SHARED="$CC -shared -m32"
		fi
		if run $CC_SHARED $CC_FLAGS $CC_LIBS $CONFTMP/test-lib.c -o $CONFTMP/test-lib.so ; then
		    log "-shared works"
		else
		    log "no -shared, aborting dlfcn test"
		    CC_SHARED=
		    OK=
		fi
	    fi
	    if [ "$OK" ] ; then
		if run $CONFTMP/test ; then
		    a=`$CONFTMP/test 2>/dev/null`
		    log "missing-symbol test: $CONFTMP/test => $a"
		    if [ "x$a" = "x0" ] ; then
			log "missing-symbol test succeeded"
		    else
			log "missing-symbol test failed"
			OK=
		    fi
		else
		    log "couldn't run missing-symbol test program"
		    OK=
		fi
	    fi
	    if [ "$OK" ] ; then
		cat >$CONFTMP/test-dynamic2.c <<EOT
		    #include <stdio.h>
		    int main(int argc, char **argv) {
			printf("%d\n", foo(atoi(argv[1])));
		    }
		    int quux(int xyzzy) {
			return xyzzy+1;
		    }
EOT
		cat >$CONFTMP/test-dynamic.c <<EOT
		    int foo(int bar) {
			return quux(bar)*2;
		    }
EOT
		if run $CC_SHARED $CC_FLAGS $CC_LIBS $CONFTMP/test-dynamic.c -o $CONFTMP/test.so \
		&& run $CC $CC_FLAGS $CC_DYN_LFLAGS $CC_LIBS $CC_DYN_LIBS $CONFTMP/test-dynamic2.c $CONFTMP/test.so -o $CONFTMP/test
		then
		    a=`$CONFTMP/test 1`
		    log "symbol resolution test: $CONFTMP/test 1 => $a"
		    if [ "x$a" = "x4" ] ; then
			log "symbol resolution test: succeeded => using dynamic modules (dlfcn)"
		    else
			log "symbol resolution test: bad output (expected 4)"
			OK=
		    fi
		else
		    log "symbol resolution test: dynamic compile failed"
		    OK=
		fi
	    fi
	fi  # dlfcn test
	if [ "$OK" ] ; then
	    log "checking for underscores in symbols"
	    cat >$CONFTMP/test-dynamic2.c <<EOT
		#include <stdio.h>
	        #include <dlfcn.h>
		int main(int argc, char **argv) {
		    void *handle = dlopen(NULL, 0);
		    printf("%d%d\n", dlsym(handle,"foo")!=NULL ? 1 : 0,
				     dlsym(handle,"_foo")!=NULL ? 1 : 0);
		    return 0;
		}
		int quux(int x) {return x;}
EOT
	    if run $CC $CC_FLAGS $CC_DYN_LFLAGS $CC_LIBS $CC_DYN_LIBS $CONFTMP/test-dynamic2.c $CONFTMP/test.so -o $CONFTMP/test
	    then
		a=`$CONFTMP/test`
		log "underscore test: $CONFTMP/test => $a"
		with_underscore=`echo "$a" | cut -c2`
		without_underscore=`echo "$a" | cut -c1`
		if [ "x$with_underscore" = "x1" ] ; then
		    log "underscore test: succeeded with preceding underscore"
		    SYMS_NEED_UNDERSCORES=1
		elif [ "x$without_underscore" = "x1" ] ; then
		    log "underscore test: succeeded with no preceding underscore"
		    SYMS_NEED_UNDERSCORES=0
		else
		    log "underscore test: failed?! (bizarre output)"
		    OK=
		fi
	    else
		log "underscore test: dynamic compile failed"
		OK=
	    fi
	fi  # underscore test
	if [ "$OK" ] ; then
	    echo "yes."
	    STATIC_MODULES=0
	else
	    log "static modules selected"
	    echo "no."
	    STATIC_MODULES=1
	    CC_SHARED=
	    CC_DYN_LFLAGS=
	    CC_DYN_LIBS=
	    SYMS_NEED_UNDERSCORES=
	fi
    fi
fi

# Also check for ranlib, and use it if found.
MODE="check_ranlib       "
echo2 "Checking whether ranlib exists... "
if [ "$RANLIB" ] ; then
    if [ "x$RANLIB" = xranlib ] ; then
	log "cache says yes"
	echo "(cached) yes."
    else
	log "cache says no"
	echo "(cached) no."
    fi
else
    if run echo test >$CONFTMP/testfile ; then : ; else
	log "couldn't create temp file!"
	echo ""
	echo ""
	echo "*** WHOA THERE! ***"
	echo ""
	echo "Unable to create a temporary file!"
	echo "Are you out of disk space?"
	exit 4
    fi
    if run ar -rc $CONFTMP/test.a $CONFTMP/testfile ; then
	if run ranlib $CONFTMP/test.a ; then
	    log "ranlib found"
	    RANLIB=ranlib
	    echo "yes."
	else
	    log "ranlib not found"
	    RANLIB='echo >/dev/null'
	    echo "no."
	fi
    else  # no ar
	log "couldn't run ar!"
	if [ $STATIC_MODULES = 1 ] ; then
	    echo ""
	    cat <<EOT

*** WHOA THERE! ***

The \`ar' program could not be executed.  This program is needed to
compile Services, and is installed on most systems by default; make
certain it is in your executable search path (for example, Solaris users
may need to add /usr/ccs/bin to the search path) and re-run this script.

Configuration aborted.

EOT
	    exit 4
	else
	    log "ar not found, assuming no ranlib"
	    RANLIB='echo >/dev/null'
	    echo "no."
	    cat <<EOT

NOTICE: The \`ar' command was not found on your system.  This is not an
        immediate problem, but it will prevent you from compiling
        Services using static modules.  Please check and make certain
        your executable search path is correct.

EOT
	    echo2 "Press Enter to continue: "
	    read dummy
	fi
    fi
fi

###########################################################################

# See what sizes various types are.

MODE="check_int16        "
echo2 "Looking for an 8-bit integer type... "
if [ "$TYPE_INT8" ] ; then
    echo "(cached) $TYPE_INT8"
    log "cache supplied $TYPE_INT8"
else
    cat >$CONFTMP/test.c <<EOT
	int main() {
	    char a;
	    printf("%d", sizeof(a));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
	a="`$CONFTMP/test`"
	log "test program output (sizeof(char)): $a"
	if [ ! "$a" ] ; then
	    echo "test program failed!  Assuming short."
	    log "assuming short"
	    TYPE_INT16=short
	elif [ "$a" = 1 ] ; then
	    echo char
	    log "char is 8 bits"
	    TYPE_INT8=char
	else
	    cat >$CONFTMP/test.c <<EOT
		int main() {
		    byte a;
		    printf("%d", sizeof(a));
		    return 0;
		}
EOT
	    if run $CC $CC_FLAGS $CONFTMP/tset.c $CC_LIBS -o $CONFTMP/test ; then
		a="`$CONFTMP/test`"
		log "test program 2 output (sizeof(byte)): $a"
		if [ "$a" = 1 ] ; then
		    echo byte
		    log "byte is 8 bits"
		    TYPE_INT8=byte
		fi
	    else
		log "couldn't compile test program 2, assuming no byte type"
	    fi
	    if [ ! "$TYPE_INT8" ] ; then
		echo "none found?!"
		cat <<EOF
    Services requires an 8-bit integer type.  Please check your system
    configuration.

Configuration aborted.

EOF
		exit 1
	    fi
	fi
    else
	whoa_there
    fi
fi

MODE="check_int16        "
echo2 "Looking for a 16-bit integer type... "
if [ "$TYPE_INT16" ] ; then
    echo "(cached) $TYPE_INT16"
    log "cache supplied $TYPE_INT16"
else
    cat >$CONFTMP/test.c <<EOT
	int main() {
	    int a;
	    short b;
	    printf("%d %d", sizeof(a), sizeof(b));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
	a="`$CONFTMP/test`"
	log "test program output (sizeof(int) sizeof(short)): $a"
	if [ ! "$a" ] ; then
	    echo "test program failed!  Assuming short."
	    log "assuming short"
	    TYPE_INT16=short
	else
	    size_int=`echo $a | cut -d\  -f1`
	    size_short=`echo $a | cut -d\  -f2`
	    if [ $size_int = 2 ] ; then
		echo int
		log "int is 16 bits"
		TYPE_INT16=int
	    elif [ $size_short = 2 ] ; then
		echo short
		log "short is 16 bits"
		TYPE_INT16=short
	    else
		echo "none found?!"
		cat <<EOF
    Services requires a 16-bit integer type.  Please check your system
    configuration.

Configuration aborted.

EOF
		exit 1
	    fi
	fi
    else
	whoa_there
    fi
fi

MODE="check_int32        "
echo2 "Looking for a 32-bit integer type... "
if [ "$TYPE_INT32" ] ; then
    echo "(cached) $TYPE_INT32"
    log "cache supplied $TYPE_INT32"
else
    cat >$CONFTMP/test.c <<EOT
	int main() {
	    int a;
	    long b;
	    printf("%d %d", sizeof(a), sizeof(b));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
	a="`$CONFTMP/test`"
	log "test program output (sizeof(int) sizeof(long)): $a"
	if [ ! "$a" ] ; then
	    echo "test program failed!  Assuming long."
	    log "assuming long"
	    TYPE_INT32=long
	else
	    size_int=`echo $a | cut -d\  -f1`
	    size_long=`echo $a | cut -d\  -f2`
	    if [ $size_int = 4 ] ; then
		echo int
		log "int is 32 bits"
		TYPE_INT32=int
	    elif [ $size_long = 4 ] ; then
		echo long
		log "long is 32 bits"
		TYPE_INT32=long
	    else
		echo "none found?!"
		cat <<EOF
    Services requires a 32-bit integer type.  Please check your system
    configuration.

Configuration aborted.

EOF
		exit 1
	    fi
	fi
    else
	whoa_there
    fi
fi

MODE="check_int_size     "
echo2 "Checking the size of int... "
if [ "$SIZEOF_INT" ] ; then
    echo "(cached) `expr $SIZEOF_INT \* 8` bits"
    log "cache supplied `expr $SIZEOF_INT \* 8` bits"
else
    cat >$CONFTMP/test.c <<EOT
	int main() {
	    int a = 0;
	    printf("%d", sizeof(a));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
	a="`$CONFTMP/test`"
	log "test program output (sizeof(int)): $a"
	if [ ! "$a" ] ; then
	    echo "test program failed!  Assuming 16 bits."
	    log "assuming 16 bits"
	    SIZEOF_INT=2
	else
	    SIZEOF_INT="$a"
	    if [ $SIZEOF_INT -lt 2 ] ; then
		echo "`expr $SIZEOF_INT \* 8` bits... huh?"
		cat <<EOF
    \`int' must be at least 16 bits.  Please check your compiler
    settings.

Configuration aborted.

EOF
		exit 1
	    else
		echo `expr $SIZEOF_INT \* 8` bits
		log "`expr $SIZEOF_INT \* 8` bits"
	    fi
	fi
    else
	whoa_there
    fi
fi

MODE="check_time_t       "
echo2 "Checking the size of time_t... "
if [ "$SIZEOF_TIME_T" -a "$MAX_TIME_T" ] ; then
    echo "(cached) `expr $SIZEOF_TIME_T \* 8` bits"
    log "cache supplied `expr $SIZEOF_TIME_T \* 8` bits, max $MAX_TIME_T"
else
    cat >$CONFTMP/test.c <<EOT
	#include <time.h>
	int main() {
	    time_t a = 0;
	    printf("%d ", sizeof(a));
	    if (a-1 > 0)
		printf("(~(time_t)0)");
	    else
		printf("(((time_t)1<<(sizeof(time_t)*8-2))+(((time_t)1<<(sizeof(time_t)*8-2))-1))");
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
	a="`$CONFTMP/test`"
	log "test program output (sizeof(time_t) MAX_TIME_T): $a"
	if [ ! "$a" ] ; then
	    echo "test program failed!  Assuming 32 bits."
	    log "assuming 32 bits"
	    SIZEOF_TIME_T=4
	else
	    SIZEOF_TIME_T=`echo "$a" | cut -d\  -f1`
	    MAX_TIME_T=`echo "$a" | cut -d\  -f2`
	    if [ $SIZEOF_TIME_T = 4 ] ; then
		echo 32 bits
		log "32 bits"
	    elif [ $SIZEOF_TIME_T = 8 ] ; then
		echo "64 bits (nifty!)"
		log "64 bits"
	    elif [ $SIZEOF_TIME_T -gt 4 ] ; then
		echo "`expr $SIZEOF_TIME_T \* 8` bits... huh?"
		echo "    If you experience any problems compiling or running Services, please"
		echo "    report this."
		log "`expr $SIZEOF_TIME_T \* 8` bits"
	    else
		echo "`expr $SIZEOF_TIME_T \* 8` bits... huh?"
		cat <<EOT
    Services requires a \`time_t' of at least 32 bits.  Please check your
    system configuration.

Configuration aborted.

EOT
		log "`expr $SIZEOF_TIME_T \* 8` bits -- too small, aborting"
		exit 1
	    fi
	fi
    else
	whoa_there
    fi
fi

MODE="check_gid_t        "
echo2 "Checking the size of gid_t... "
if [ "$SIZEOF_GID_T" != bonkle ] ; then
    if [ "$SIZEOF_GID_T" ] ; then
	echo "(cached) `expr $SIZEOF_GID_T \* 8` bits"
	log "cache supplied `expr $SIZEOF_GID_T \* 8` bits"
    else
	echo "(cached) no gid_t"
	log "cache said no gid_t"
    fi
else
    cat >$CONFTMP/test.c <<EOT
	#include <sys/types.h>
	int main() {
	    gid_t a;
	    printf("%d", sizeof(a));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
	a="`$CONFTMP/test`"
	log "test program output (sizeof(gid_t)): $a"
	if [ ! "$a" ] ; then
	    echo "test program failed!  Assuming 16 bits."
	    log "assuming 16 bits"
	    SIZEOF_GID_T=2
	else
	    SIZEOF_GID_T=$a
	    if [ $SIZEOF_GID_T = 4 ] ; then
		echo 32 bits
		log "32 bits"
	    elif [ $SIZEOF_GID_T = 2 ] ; then
		echo "16 bits"
		log "16 bits"
	    else
		echo "`expr $SIZEOF_GID_T \* 8` bits... huh?"
		echo "    If you experience any problems compiling or running Services, please"
		echo "    report this."
		log "`expr $SIZEOF_GID_T \* 8` bits"
	    fi
	fi
    else
	echo "no gid_t found."
	log "couldn't compile test program, assuming no gid_t"
	SIZEOF_GID_T=
	HAVE_SETREGID=0
    fi
fi

MODE="check_socklen_t    "
echo2 "Checking for socklen_t... "
if [ "$HAVE_SOCKLEN_T" ] ; then
    if [ $HAVE_SOCKLEN_T = 1 ] ; then
	echo "(cached) present."
	log "cache said present"
    else
	echo "(cached) not present."
	log "cache said not present"
    fi
else
    cat >$CONFTMP/test.c <<EOT
	#include <unistd.h>
	#include <sys/socket.h>
	int main() {
	    socklen_t a;
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
	log "socklen_t found"
	echo "present."
	HAVE_SOCKLEN_T=1
    else
	log "socklen_t not found"
	echo "not present."
	HAVE_SOCKLEN_T=0
    fi
fi

###########################################################################

# Look for include files that might or might not be here.
echo "Checking for presence of include files (it's okay if some aren't there):"

MODE="check_strings      "
echo2 "    strings.h... "
if [ "$HAVE_STRINGS_H" ] ; then
    if [ "$HAVE_STRINGS_H" = 1 ] ; then
	echo "(cached) present"
	log "cache says present"
    else
	echo "(cached) not present"
	log "cache says not present"
    fi
else
    if test_include strings.h ; then
	echo "present"
    else
	echo "not present"
    fi
fi

MODE="check_sysselect    "
echo2 "    sys/select.h... "
if [ "$HAVE_SYS_SELECT_H" ] ; then
    if [ "$HAVE_SYS_SELECT_H" = 1 ] ; then
	echo "(cached) present"
	log "cache says present"
    else
	echo "(cached) not present"
	log "cache says not present"
    fi
else
    if test_include sys/select.h ; then
	echo "present"
    else
	echo "not present"
    fi
fi

MODE="check_sysproto     "
echo2 "    sys/sysproto.h... "
if [ "$HAVE_SYS_SYSPROTO_H" ] ; then
    if [ "$HAVE_SYS_SYSPROTO_H" = 1 ] ; then
	echo "(cached) present"
	log "cache says present"
    else
	echo "(cached) not present"
	log "cache says not present"
    fi
else
    if test_include sys/sysproto.h ; then
	echo "present"
    else
	echo "not present"
    fi
fi

###########################################################################

# AIX workaround.

MODE="check_aix_intNN    "
echo2 "Seeing if your system defines int16/int32... "
res="`run egrep int16\|int32 /usr/include/sys/systypes.h`"
if [ "$res" ] ; then
    echo "found."
    echo "    (This is bad, but we can work around it.)"
    log "int16/int32 types found, enabling workaround"
    INTTYPE_WORKAROUND=1
else
    echo "not found (this is good)."
    log "int16/int32 types not found"
    INTTYPE_WORKAROUND=0
fi

###########################################################################

# Look for missing/broken built-in routines, and similar compatibility
# stuff.

MODE="check_strerror     "
if [ "$USE_LOCAL_FUNCS" ] ; then
    log "not checking (-use-local-funcs)"
    echo "Not checking for presence of strerror (-use-local-funcs specified)."
    HAVE_STRERROR=0
    HAVE_SYS_ERRLIST=0
else
    echo2 "How to complain when something goes wrong... "
    if [ "$HAVE_STRERROR" ] ; then
	if [ "$HAVE_STRERROR" = 1 ] ; then
	    echo "(cached) strerror()."
	    log "cache supplied strerror()"
	elif [ "$HAVE_SYS_ERRLIST" = 1 ] ; then
	    echo "(cached) sys_errlist."
	    log "cache supplied sys_errlist"
	else
	    HAVE_SYS_ERRLIST=0	# just in case... you never know.
	    echo "(cached) pseudo sys_errlist."
	    log "cache supplied pseudo sys_errlist"
	fi
    else
	cat >$CONFTMP/test.c <<EOT
	    int main() {
		extern void strerror(void);
		strerror();
	    }
EOT
	if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
	    HAVE_STRERROR=1
	    echo "ah, strerror() is here."
	    log "using strerror()"
	else
	    HAVE_STRERROR=0
	    echo "no strerror()."
	    cat >$CONFTMP/test.c <<EOT
		int main() {
		    extern char *sys_errlist[];
		    char *s;
		    s = sys_errlist[0];
		}
EOT
	    log "trying sys_errlist..."
	    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
		HAVE_SYS_ERRLIST=1
		echo "    But you have sys_errlist, which will do nicely."
		log "using sys_errlist"
	    else
		HAVE_SYS_ERRLIST=0
		echo "    You don't have sys_errlist either, so we'll have to make do."
		log "using pseudo sys_errlist"
	    fi
	fi
    fi
fi  # -use-local-funcs


MODE="check_compat       "

if [ "$USE_LOCAL_FUNCS" ] ; then
    echo "Enabling compatibility functions: hstrerror snprintf strtok str[n]icmp strdup str[c]spn strsignal"
    HAVE_HSTRERROR=0
    HAVE_SNPRINTF=0
    BAD_SNPRINTF=0
    HAVE_STRTOK=0
    HAVE_STRICMP=0
    HAVE_STRCASECMP=0
    HAVE_STRDUP=0
    HAVE_STRSPN=0
    HAVE_STRSIGNAL=0
fi

echo2 "Looking for other routines we want that you don't have... "

if [ "$MISSING" != bonkle -a ! "$USE_LOCAL_FUNCS" ] ; then
    if [ ! "$MISSING" ] ; then
	echo "(cached) none"
	log "cache supplied: (none)"
    else
	echo "(cached)$MISSING"
	log "cache supplied:$MISSING"
    fi
else

    if [ "$USE_LOCAL_FUNCS" ] ; then

	MISSING=" hstrerror snprintf strtok str[n]icmp strdup str[c]spn strsignal"

    else

	MISSING=

	MODE="check_hstrerror    "
	TEST="(void) hstrerror(1); return 0;"
	if test_function "const char *" hstrerror "(int)" ; then : ; else
	    MISSING="$MISSING hstrerror"
	    echo2 "hstrerror "
	fi

	MODE="check_snprintf     "
	TEST='	char buf[16];
		int res;
		buf[0] = 0;
		res = snprintf(buf, 8, "%d", 123456789);
		if (strcmp(buf, "1234567") != 0) {
		    printf("test: snprintf broken (bad result in buffer: wanted 1234567, got \"%s\")\n", buf);
		    if (strlen(buf) > 7)
			printf("test: your snprintf does not check buffer size!\n");
			return 1;
		    } else if (res != 7) {
			printf("test: snprintf broken (wrong return value: wanted 7, got %d)\n", res);
			return 1;
		    } else
			return 0;'
	if test_function int snprintf "(char *, int, const char *, ...)" ; then
	    BAD_SNPRINTF=0
	else
	    tmp="`$CONFTMP/test 2>&1`"
	    res="`echo $tmp | cut -d\  -f10 2>&1`"
	    if [ "$res" = "-1)" ] ; then
		BAD_SNPRINTF=1
		log "found, but returns -1 if string too long"
	    elif [ "$res" = "9)" ] ; then
		BAD_SNPRINTF=2
		log "found, but returns large value if string too long"
	    else
		BAD_SNPRINTF=0
		MISSING="$MISSING snprintf"
		echo2 "snprintf "
	    fi
	fi

	# Common failings with strtok() implementations:
	# - strtok(NULL, ...) crashes after a NULL is returned
	# - strtok(NULL, " ") returns NULL but strtok(NULL, "") doesn't
	MODE="check_strtok       "
	TEST='	char buf1[1];
		char buf2[] = "1 2 3";
		char buf3[] = "4 5 6";
		char buf4[] = "     ";
		buf1[0] = 0;
		buf3[0] = 0;
		if (strtok(buf1, " ") != (char *)0)
		    return 1;
		if (strtok((char *)0, " ") != (char *)0)
		    return 2;
		if (strtok(buf2, " ") != buf2)
		    return 3;
		if (strtok((char *)0, " ") != buf2+2)
		    return 4;
		if (strtok(buf3, " ") != (char *)0)
		    return 5;
		if (strtok((char *)0, " ") != (char *)0)
		    return 6;
		if (strtok(buf4, " ") != (char *)0)
		    return 7;
		if (strtok((char *)0, "") != (char *)0)
		    return 8;
		return 0;'
	if test_function "char *" strtok "(char *, const char *)" ; then : ; else
	    MISSING="$MISSING strtok"
	    echo2 "strtok "
	fi

	# stricmp() (STRing case-Insensitive CoMPare) is another name, used
	# by at least the Amiga DICE C compiler, for what POSIX calls
	# strcasecmp().  I prefer the former because the latter (1) is
	# unnecessarily long and (2) implies a case-sensitive compare when
	# it's really a case-INsensitive compare.  If this system doesn't
	# have stricmp() but does have strcasecmp(), we use a #define in
	# defs.h to rename the latter to the former.
	MODE="check_stricmp      "
	    TEST='extern int strnicmp(const char *, const char *, int); return stricmp("ABC","abc")==0 && strnicmp("ABC","abd",2)==0 ? 0 : 1;'
	if test_function int stricmp "(const char *, const char *)" ; then
	    HAVE_STRCASECMP=0	# doesn't really matter
	else
	    TEST='extern int strncasecmp(const char *, const char *, int); return strcasecmp("ABC","abc")==0 && strncasecmp("ABC","abd",2)==0 ? 0 : 1;'
	    if test_function int strcasecmp "(const char *, const char *)" ; then : ; else
		MISSING="$MISSING str[n]icmp"
		echo2 "str[n]icmp "
	    fi
	fi

	MODE="check_strdup       "
	TEST='	char *s, *t;
		s = "ABC";
		t = strdup(s);'"
		return (t != (char *)0 && t[0]=='A' && t[1]=='B' && t[2]=='C' && t[3]==0) ? 0 : 1;"
	if test_function "char *" strdup "(const char *)" ; then : ; else
	    MISSING="$MISSING strdup"
	    echo2 "strdup "
	fi

	MODE="check_strspn       "
	TEST='	extern int strcspn(const char *, const char *);
		return (strspn("ABCBA","BA")==2 && strspn("123","123")==3
		     && strcspn("ABCBA","C")==2 && strcspn("123","4")==3) ? 0 : 1;'
	if test_function int strspn "(const char *, const char *)" ; then : ; else
	    MISSING="$MISSING str[c]spn"
	    echo2 "str[c]spn "
	fi

	MODE="check_strsignal    "
	TEST="(void) strsignal(1); return 0;"
	if test_function "char *" strsignal "(int)" ; then : ; else
	    MISSING="$MISSING strsignal"
	    echo2 "strsignal "
	fi

    fi  # -use-local-funcs

    MODE="check_gettimeofday "
    TEST="char buf[256]; (void) gettimeofday((void *)buf, (void *)buf); return 0;"
    if test_function "char *" gettimeofday "(void *, void *)" ; then : ; else
	MISSING="$MISSING gettimeofday"
	echo2 "gettimeofday "
    fi

    MODE="check_setgrent     "
    if [ "$SIZEOF_GID_T" ] ; then
	TEST="(void) setgrent(); return 0;"
	if test_function int setgrent "(void)" ; then : ; else
	    MISSING="$MISSING setgrent"
	    echo2 "setgrent "
	fi
    else
	log "skipped (no gid_t)"
	HAVE_SETGRENT=0
    fi

    MODE="check_setregid     "
    if [ "$SIZEOF_GID_T" ] ; then
	TEST="(void) setregid(-1,-1); return 0;"
	if test_function int setregid "(int,int)" ; then : ; else
	    MISSING="$MISSING setregid"
	    echo2 "setregid "
	fi
    else
	log "skipped (no gid_t)"
	HAVE_SETREGID=0
    fi

    MODE="check_umask        "
    TEST="(void) umask(1); return 0;"
    if test_function int umask "(int)" ; then : ; else
	MISSING="$MISSING umask"
	echo2 "umask "
    fi

    MODE="check_fork         "
    TEST="(void) fork(); return 0;"
    if test_function int fork "(void)" ; then : ; else
	MISSING="$MISSING fork"
	echo2 "fork "
    fi

    MODE="check_gethostbyname"
    TEST='(void) gethostbyname("localhost"); return 0;'
    if test_function "struct hostent *" gethostbyname "(const char *)" ; then : ; else
	MISSING="$MISSING gethostbyname"
	echo2 "gethostbyname "
    fi

    MODE="check_getsetrlimit "
    cat >$CONFTMP/test.c <<EOT
	int main() {
	    extern void getrlimit(), setrlimit();
	    getrlimit();
	    setrlimit();
	}
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then
	log "found getrlimit/setrlimit"
	HAVE_GETSETRLIMIT=1
    else
	log "didn't find getrlimit/setrlimit"
	HAVE_GETSETRLIMIT=0
	MISSING="$MISSING get/setrlimit"
	echo2 "get/setrlimit "
    fi

    echo ""
fi

if [ "$HAVE_GETHOSTBYNAME" = 0 ] ; then
    cat <<EOT

NOTICE: Your system does not seem to have the gethostbyname() function.
        This function is used to translate hostnames into IP addresses.
        Since you don't have it (or we can't find it), you will need to
        use IP addresses instead of hostnames when setting the remote
        server address in services.conf.

EOT
    echo2 "Press Enter to continue: "
    read dummy
fi

###########################################################################

MODE="check_install      "
echo2 "Checking how to install files... "

if [ "$INSTALL" -a "$OLD_RUNGROUP" = "$RUNGROUP" ] ; then
    if [ "`echo $INSTALL | cut -c1`" = "$" ] ; then
	echo '(cached) using our own "install".'
	log "cache says use our own"
    else
	echo '(cached) this system'\''s "install" works.'
	log "cache says use regular "\`"install'"
    fi
else
    cat >$CONFTMP/test.c <<EOT
	int main() { return 0; }
EOT
    if run $CC $CC_FLAGS $CONFTMP/test.c $CC_LIBS -o $CONFTMP/test ; then : ; else
	whoa_there
    fi
    if run cp -p $CONFTMP/test$EXE_SUFFIX $CONFTMP/test3$EXE_SUFFIX ; then : ; else
	echo ""
	echo ""
	echo "*** WHOA THERE! ***"
	echo ""
	echo "A simple "\`"cp -p' failed!"
	echo "Are you out of disk space?"
	exit 4
    fi

    if run install -m 500 $CONFTMP/test$EXE_SUFFIX $CONFTMP/test2$EXE_SUFFIX && test -f $CONFTMP/test$EXE_SUFFIX && run cmp $CONFTMP/test$EXE_SUFFIX $CONFTMP/test2$EXE_SUFFIX ; then
	echo 'looks like "install" will work.'
	INSTALL="install"
    elif run cp -p $CONFTMP/test3$EXE_SUFFIX $CONFTMP/test$EXE_SUFFIX ; run install -c -m 500 $CONFTMP/test$EXE_SUFFIX $CONFTMP/test2$EXE_SUFFIX && test -f $CONFTMP/test$EXE_SUFFIX && run cmp $CONFTMP/test$EXE_SUFFIX $CONFTMP/test2$EXE_SUFFIX ; then
	echo 'looks like "install -c" will work.'
	INSTALL="install -c"
    elif run cp -p $CONFTMP/test3$EXE_SUFFIX $CONFTMP/test$EXE_SUFFIX ; run ginstall -m 500 $CONFTMP/test$EXE_SUFFIX $CONFTMP/test2$EXE_SUFFIX && test -f $CONFTMP/test$EXE_SUFFIX && run cmp $CONFTMP/test$EXE_SUFFIX $CONFTMP/test2$EXE_SUFFIX ; then
	echo 'looks like "ginstall" will work.'
	INSTALL="ginstall"
    else
	echo \"install\"" doesn't seem to work."
	echo "    But we can still use cp and friends, so we'll roll our own "\"install\".
	INSTALL='$(TOPDIR)/install-script'
    fi
    log "using: $INSTALL"
fi

###########################################################################

MODE="check_install-d    "

if [ "$INSTALL" = '$(TOPDIR)/install-script' ] ; then
    MKDIR='$(INSTALL) -d'
else
    tmp=`echo $INSTALL | cut -d\  -f1`
    echo2 "Seeing if \"$tmp\" will create directories... "
    if [ "$MKDIR" ] ; then
	if [ "$MKDIR" = '$(TOPDIR)/install-script' ] ; then
	    echo "(cached) no"
	    log "cache says no"
	else
	    echo "(cached) yes"
	    log "cache says yes"
	fi
    else
	MKDIR=$tmp
	log "trying $MKDIR"
	if run $MKDIR -d -m 700 $CONFTMP/testdir && test -d $CONFTMP/testdir ; then
	    echo "OK."
	    log "successful"
	else
	    echo "nope, using workaround."
	    log "failed"
	    MKDIR='$(TOPDIR)/install-script'
	fi
    fi
fi

###########################################################################

MODE="check_copy_recurse "
echo2 "Checking how to copy directories... "

if [ "$CP_ALL" ] ; then
    echo "(cached) $CP_ALL"
    log "cache supplied $CP_ALL"
else
    sysname=`/bin/uname -s 2>&1`
    log "sysname: $sysname"
    case $sysname in
	Linux)  CP_ALL="/bin/cp -dpr";
	        log "guessing: cp -dpr";;
	CYGWIN) CP_ALL="/bin/cp -dpr";
	        log "guessing: cp -dpr";;
	*)      CP_ALL="/bin/cp -pr";
	        log "guessing: cp -pr";;
    esac
    run rm -rf $CONFTMP/test*
    run echo test >$CONFTMP/test
    run cp $CONFTMP/test $CONFTMP/test2
    if run /bin/mkdir $CONFTMP/testA && run /bin/mkdir $CONFTMP/testB && run /bin/mv $CONFTMP/test2 $CONFTMP/testA ; then
	:
    else
	echo ""
	echo ""
	echo "*** WHOA THERE! ***"
	echo ""
	echo "A few simple mkdir's and mv's failed!"
	echo "Are you out of disk space?"
	exit 4
    fi
    if run $CP_ALL $CONFTMP/testA $CONFTMP/testB/testC && run cmp $CONFTMP/testA/test2 $CONFTMP/testB/testC/test2 ; then
	echo "$CP_ALL"
	log \`"$CP_ALL' works"
    else
	log \`"$CP_ALL' doesn't work"
	run /bin/rm -rf $CONFTMP/testB/*
	if run sh -c '/bin/tar Ccf $CONFTMP/testA - . | /bin/tar Cxf $CONFTMP/testB -'
	then
	    echo "tar (yuck)"
	    CP_ALL='$(TOPDIR)/cp-recursive -t'
	    log "using tar"
	else
	    log "tar failed(!)"
	    echo ""
	    echo "    Neither cp nor tar work!  I give up."
	    exit 2
	fi
    fi
fi

###########################################################################

# Create files.

echo2 "Creating config.h... "
rm -f config.h.new
cat >config.h.new <<EOT
/*
 * This file is generated automatically by "configure".  Any changes made
 * to it will be erased next time "configure" is run.
 */

#define SERVICES_BIN		"$BINDEST/$PROGRAM"
#define SERVICES_DIR		"$DATDEST"
EOT
if [ "$NO_VARARG_MACROS" ] ; then cat >>config.h.new <<EOT ; fi
#define NO_VARARG_MACROS
EOT
if [ "$NO_VA_COPY" ] ; then cat >>config.h.new <<EOT ; fi
#define NO_VA_COPY
EOT
if [ "$NEED_GCC3_HACK" ] ; then cat >>config.h.new <<EOT ; fi
#define GCC3_HACK
EOT
if [ "$CLEAN_COMPILE" ] ; then cat >>config.h.new <<EOT ; fi
#define CLEAN_COMPILE
EOT
if [ "$DUMPCORE" ] ; then cat >>config.h.new <<EOT ; fi
#define DUMPCORE
EOT
if [ "$MEMCHECKS" ] ; then cat >>config.h.new <<EOT ; fi
#ifndef CONVERT_DB
# define MEMCHECKS
#endif
EOT
if [ "$SHOWALLOCS" ] ; then cat >>config.h.new <<EOT ; fi
#ifdef MEMCHECKS
# define SHOWALLOCS
#endif
EOT
echo "" >>config.h.new
if [ "x$SYMS_NEED_UNDERSCORES" = x1 ] ; then cat >>config.h.new <<EOT ; fi
#define SYMS_NEED_UNDERSCORES

EOT
cat >>config.h.new <<EOT
typedef   signed $TYPE_INT8   int8;
typedef unsigned $TYPE_INT8  uint8;
typedef   signed $TYPE_INT16  int16;
typedef unsigned $TYPE_INT16 uint16;
typedef   signed $TYPE_INT32  int32;
typedef unsigned $TYPE_INT32 uint32;

#define SIZEOF_INT		$SIZEOF_INT
#define SIZEOF_LONG		4
#define SIZEOF_TIME_T		$SIZEOF_TIME_T
#define MAX_TIME_T		$MAX_TIME_T
EOT
if [ "$SIZEOF_GID_T" ] ; then cat >>config.h.new <<EOT ; fi
#define SIZEOF_GID_T		$SIZEOF_GID_T
EOT
cat >>config.h.new <<EOT
#define HAVE_SOCKLEN_T		$HAVE_SOCKLEN_T

#define HAVE_STRINGS_H		$HAVE_STRINGS_H
#define HAVE_SYS_SELECT_H	$HAVE_SYS_SELECT_H
#define HAVE_SYS_SYSPROTO_H	$HAVE_SYS_SYSPROTO_H

#define HAVE_STRERROR		$HAVE_STRERROR
#define HAVE_SYS_ERRLIST	$HAVE_SYS_ERRLIST
#define HAVE_HSTRERROR		$HAVE_HSTRERROR
#define HAVE_SNPRINTF		$HAVE_SNPRINTF
#define BAD_SNPRINTF		$BAD_SNPRINTF
#define HAVE_STRTOK		$HAVE_STRTOK
#define HAVE_STRICMP		$HAVE_STRICMP
#define HAVE_STRCASECMP		$HAVE_STRCASECMP
#define HAVE_STRDUP		$HAVE_STRDUP
#define HAVE_STRSPN		$HAVE_STRSPN
#define HAVE_STRSIGNAL		$HAVE_STRSIGNAL
#define HAVE_GETTIMEOFDAY	$HAVE_GETTIMEOFDAY
#define HAVE_SETGRENT		$HAVE_SETGRENT
#define HAVE_SETREGID		$HAVE_SETREGID
#define HAVE_UMASK		$HAVE_UMASK
#define HAVE_FORK		$HAVE_FORK
#define HAVE_GETHOSTBYNAME	$HAVE_GETHOSTBYNAME
#define HAVE_GETSETRLIMIT	$HAVE_GETSETRLIMIT
EOT

if [ "x$FORCE_GCC_2_96" = "xforced" ] ; then cat >>config.h.new <<EOT ; fi
#define FORCED_GCC_2_96
EOT

if cmp config.h config.h.new >/dev/null 2>&1 ; then
    rm -f config.h.new
    echo "done (unchanged)."
else
    mv -f config.h.new config.h
    echo "done."
fi

###########################################################################

INSTEXEFLAGS="-m 750"
INSTDATFLAGS="-m 640"
MKDIRFLAGS="-m 750"

echo2 "Creating Makefile.inc... "
rm -f Makefile.inc.new
cat >Makefile.inc.new <<EOT
# This file is generated automatically by "configure".  Any changes made
# to it will be erased next time "configure" is run.

CC=$CC
BASE_CFLAGS=$CC_FLAGS
CDEFS=$CDEFS
LFLAGS=$CC_LFLAGS$CC_DYN_LFLAGS
LIBS=$CC_LIBS$CC_DYN_LIBS
EXE_SUFFIX=$EXE_SUFFIX
EOT
if [ $STATIC_MODULES = 1 ] ; then
    cat >>Makefile.inc.new <<EOT
STATIC_MODULES=1
EOT
else
    cat >>Makefile.inc.new <<EOT
CC_SHARED=$CC_SHARED
EOT
fi
if [ $HAVE_SNPRINTF = 0 -a $BAD_SNPRINTF = 0 ] ; then
    cat >>Makefile.inc.new <<EOT

VSNPRINTF_O=vsnprintf.o
EOT
fi
cat >>Makefile.inc.new <<EOT
RANLIB=$RANLIB

PROGRAM=$PROGRAM
BINDEST=$BINDEST
DATDEST=$DATDEST

TEST_NT=$TEST_NT
INSTALL_EXE=$INSTALL $INSTEXEFLAGS
INSTALL_DAT=$INSTALL $INSTDATFLAGS
MKDIR=$MKDIR -d $MKDIRFLAGS
CP_ALL=$CP_ALL
RUNGROUP=$RUNGROUP
EOT

if cmp Makefile.inc Makefile.inc.new >/dev/null 2>&1 ; then
    rm -f Makefile.inc.new
    echo "done (unchanged)."
else
    mv -f Makefile.inc.new Makefile.inc
    echo "done."
fi

###########################################################################

# Save results in cache for next time around.

echo2 "Saving configuration results in config.cache... "

cat <<EOT >config.cache
CONFIG_VERSION=$MY_CONFIG_VERSION

BINDEST='$BINDEST'
DATDEST='$DATDEST'

TEST_NT='$TEST_NT'
INSTALL='$INSTALL'
MKDIR='$MKDIR'
CP_ALL='$CP_ALL'

CC='$CC'
CC_FLAGS='$CC_FLAGS'
CC_LFLAGS='$CC_LFLAGS'
CC_LIBS='$CC_LIBS'

CLEAN_COMPILE=$CLEAN_COMPILE
MEMCHECKS=$MEMCHECKS
SHOWALLOCS=$SHOWALLOCS
DUMPCORE=$DUMPCORE

STATIC_MODULES=$STATIC_MODULES
CC_SHARED='$CC_SHARED'
CC_DYN_LFLAGS='$CC_DYN_LFLAGS'
CC_DYN_LIBS='$CC_DYN_LIBS'
SYMS_NEED_UNDERSCORES=$SYMS_NEED_UNDERSCORES
RANLIB='$RANLIB'

TYPE_INT8=$TYPE_INT8
TYPE_INT16=$TYPE_INT16
TYPE_INT32=$TYPE_INT32
SIZEOF_INT=$SIZEOF_INT
SIZEOF_LONG=4
SIZEOF_TIME_T=$SIZEOF_TIME_T
MAX_TIME_T='$MAX_TIME_T'
SIZEOF_GID_T=$SIZEOF_GID_T
HAVE_SOCKLEN_T=$HAVE_SOCKLEN_T

HAVE_STRINGS_H=$HAVE_STRINGS_H
HAVE_SYS_SELECT_H=$HAVE_SYS_SELECT_H
HAVE_SYS_SYSPROTO_H=$HAVE_SYS_SYSPROTO_H

HAVE_STRERROR=$HAVE_STRERROR
HAVE_SYS_ERRLIST=$HAVE_SYS_ERRLIST

HAVE_SNPRINTF=$HAVE_SNPRINTF
BAD_SNPRINTF=$BAD_SNPRINTF
HAVE_HSTRERROR=$HAVE_HSTRERROR
HAVE_STRTOK=$HAVE_STRTOK
HAVE_STRICMP=$HAVE_STRICMP
HAVE_STRCASECMP=$HAVE_STRCASECMP
HAVE_STRDUP=$HAVE_STRDUP
HAVE_STRSPN=$HAVE_STRSPN
HAVE_STRSIGNAL=$HAVE_STRSIGNAL
HAVE_GETTIMEOFDAY=$HAVE_GETTIMEOFDAY
HAVE_SETGRENT=$HAVE_SETGRENT
HAVE_SETREGID=$HAVE_SETREGID
HAVE_UMASK=$HAVE_UMASK
HAVE_FORK=$HAVE_FORK
HAVE_GETHOSTBYNAME=$HAVE_GETHOSTBYNAME
HAVE_GETSETRLIMIT=$HAVE_GETSETRLIMIT
MISSING='$MISSING'
EOT

if [ "x$FORCE_GCC_2_96" = "xforced" ] ; then cat >>config.cache <<EOT ; fi
FORCED_GCC_2_96=y
EOT

echo "done."

###########################################################################

# Delete the temporary directory we created.

rm -rf $CONFTMP

###########################################################################

# All done!

cat <<EOT

All done!  Now edit defs.h as needed, and run "make" (or possibly "gmake")
to compile Services.  See the README and FAQ if you have any problems.

EOT

exit 0
