#!/bin/sh
#
# Configuration script for Services.
#
# IRC Services is copyright (c) 1996-2002 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.

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

# 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
}

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

# 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 >tmp/test.c <<EOT
#include <$include>
int main() { return 0; }
EOT
    if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/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 >tmp/test.c <<EOT
    int main() {
	extern int $func$proto;
	$TEST
    }
EOT
    if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test && (run tmp/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 tmp/test.c $CC_LIBS -o tmp/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.

EOT
    exit 4
}

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

# Create a temporary directory for our use.

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

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

# Variable initialization.

MY_CONFIG_VERSION=2
CONFIG_VERSION=

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

INSTALL=
MKDIR=
CP_ALL=

CC=
CC_FLAGS=bonkle
CC_LFLAGS=bonkle
CC_LIBS=bonkle
EXE_SUFFIX=bonkle

CLEAN_COMPILE=y
MEMCHECKS=
DUMPCORE=y

STATIC_MODULES=
CC_SHARED=
CC_DYN_LFLAGS=
CC_DYN_LIBS=
SYMS_NEED_UNDERSCORES=

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

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=

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

# 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_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_DUMPCORE
export 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" = "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"
	    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" = "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 ***

        -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)
        -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.


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 [ "$USE_DYNAMIC_MODULES" ] ; then
	STATIC_MODULES=
    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_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 "$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

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

# Search for a compiler.

MODE="find_cc         "
echo2 "Searching for a suitable compiler... "
if [ "$USER_CC" ] ; then
    CC="$USER_CC"
    if $CC --version 2>&1 | fgrep -q 2.96 ; 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 -fno-strict-aliasing"
	else
	    cat <<EOT
Please upgrade GCC to a newer version, or downgrade to
version 2.95.3, 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 \`"$USER_CC'"
	DEF_CC_FLAGS=
    fi
elif [ "$CC" ] ; then
    echo "(cached) using $CC."
    log cache supplied \`"$CC'"
elif run gcc --version ; then
    if gcc --version 2>&1 | fgrep -q 2.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 or downgrading it to version
2.95.3, which is known to work.

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 -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,
or downgrading to version 2.95.3, which is known to work.
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 -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 -fno-strict-aliasing"
	else
	    cat <<EOT
Please upgrade GCC to a newer version, or downgrade to
version 2.95.3, before compiling Services.

See question B.1 in the FAQ for details.

EOT
	    log 'kgcc not found, aborting'
	    exit 1
	fi
    else
	echo "great, found gcc!"
	CC=gcc
	DEF_CC_FLAGS="-O2 -fno-strict-aliasing"
	log using \`gcc\'
    fi
else
    echo "gcc not found."
    echo2 "    Looking for alternatives... "
    echo >tmp/test.c "int main(){return 1;}"
    if run cc tmp/test.c -o tmp/test ; then
	CC=cc
    elif run c89 tmp/test.c -o tmp/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 >tmp/test.c <<EOT
    int main(int argc, char **argv) {
	extern void foo(int bar);
    }
EOT
    log "test for ANSI..."
    if run $CC tmp/test.c -o tmp/test ; then
	echo "using $CC."
	if [ "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
    DEF_CC_FLAGS=
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
    echo2 "Testing default compiler flags ($CC_FLAGS)... "
    cat >tmp/test.c <<EOT
	int main(int argc, char **argv) {
	    extern void foo(int bar);
	}
EOT
    if run $CC $CC_FLAGS -c tmp/test.c -o tmp/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

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

# 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 tmp/test tmp/test.exe
    echo >tmp/test.c "int main(){return 1;}"
    if run $CC $CC_FLAGS $CC_LFLAGS tmp/test.c -o tmp/test ; then
	if [ -f tmp/test.exe ] ; then
	    log using .exe
	    EXE_SUFFIX=.exe
	elif [ -f tmp/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=
    cat >tmp/test.c <<EOT
	int main(int argc, char **argv) {
	    extern void foo(int bar);
	}
EOT
    cat >tmp/test-socket.c <<EOT
	int main(int argc, char **argv) {
	    extern void socket();
	    socket();
	}
EOT
    cat >tmp/test-gethost.c <<EOT
	int main(int argc, char **argv) {
	    extern void gethostbyname();
	    gethostbyname();
	}
EOT
#    if run $CC $CC_FLAGS tmp/test.c -lnsl -o tmp/test ; then
#	CC_LIBS="$CC_LIBS -lnsl"
#	echo2 "-lnsl "
#    fi
    if run $CC $CC_FLAGS tmp/test-socket.c -o tmp/test ; then
	:
    elif run $CC $CC_FLAGS tmp/test-socket.c -lsocket -o tmp/test ; then
	CC_LIBS="$CC_LIBS -lsocket"
	echo2 "-lsocket "
    fi
    if run $CC $CC_FLAGS tmp/test-gethost.c -o tmp/test ; then
	:
    elif run $CC $CC_FLAGS tmp/test-gethost.c -lresolv -o tmp/test ; then
	CC_LIBS="$CC_LIBS -lresolv"
	echo2 "-lresolv "
    fi
#    if run $CC $CC_FLAGS tmp/test.c -lbsd -o tmp/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 >tmp/test-dlopen.c <<EOT
		#include <dlfcn.h>
		int main(int argc, char **argv) {
		    void *lib = dlopen("tmp/test-lib.so", RTLD_NOW);
		    printf("%d\n", lib != 0);
		    if (lib)
			dlclose(lib);
		    return 0;
		}
EOT
	    cat >tmp/test-lib.c <<EOT
		int foo() {no_such_symbol();}
EOT
	    if run $CC $CC_FLAGS $CC_LIBS tmp/test-dlopen.c -o tmp/test ; then
		CC_DYN_LIBS=""
		log "dlopen() found (no libs)"
	    elif run $CC $CC_FLAGS $CC_LIBS tmp/test-dlopen.c -ldl -o tmp/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 tmp/test-dlopen.c -o tmp/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 -Wl,-expect_unresolved"
		else
		    CC_SHARED="$CC -shared"
		fi
		if run $CC_SHARED $CC_FLAGS $CC_LIBS tmp/test-lib.c -o tmp/test-lib.so ; then
		    log "-shared works"
		else
		    log "no -shared, aborting dlfcn test"
		    CC_SHARED=
		    OK=
		fi
	    fi
	    if [ "$OK" ] ; then
		if run tmp/test ; then
		    a=`tmp/test`
		    log "missing-symbol test: tmp/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 >tmp/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 >tmp/test-dynamic.c <<EOT
		    int foo(int bar) {
			return quux(bar)*2;
		    }
EOT
		if run $CC_SHARED $CC_FLAGS $CC_LIBS tmp/test-dynamic.c -o tmp/test.so \
		&& run $CC $CC_FLAGS $CC_DYN_LFLAGS $CC_LIBS $CC_DYN_LIBS tmp/test-dynamic2.c tmp/test.so -o tmp/test
		then
		    a=`tmp/test 1`
		    log "symbol resolution test: tmp/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 >tmp/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 tmp/test-dynamic2.c tmp/test.so -o tmp/test
	    then
		a=`tmp/test`
		log "underscore test: tmp/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

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

# 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 >tmp/test.c <<EOT
	int main() {
	    char a;
	    printf("%d", sizeof(a));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test ; then
	a="`tmp/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 >tmp/test.c <<EOT
		int main() {
		    byte a;
		    printf("%d", sizeof(a));
		    return 0;
		}
EOT
	    if run $CC $CC_FLAGS tmp/tset.c $CC_LIBS -o tmp/test ; then
		a="`tmp/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 >tmp/test.c <<EOT
	int main() {
	    int a;
	    short b;
	    printf("%d %d", sizeof(a), sizeof(b));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test ; then
	a="`tmp/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 an 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 >tmp/test.c <<EOT
	int main() {
	    int a;
	    long b;
	    printf("%d %d", sizeof(a), sizeof(b));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test ; then
	a="`tmp/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 an 16-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 >tmp/test.c <<EOT
	int main() {
	    int a = 0;
	    printf("%d", sizeof(a));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test ; then
	a="`tmp/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_long_size  "
echo2 "Checking the size of long... "
if [ "$SIZEOF_LONG" ] ; then
    echo "(cached) `expr $SIZEOF_LONG \* 8` bits"
    log "cache supplied `expr $SIZEOF_LONG \* 8` bits"
else
    cat >tmp/test.c <<EOT
	int main() {
	    long a = 0;
	    printf("%d", sizeof(a));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test ; then
	a="`tmp/test`"
	log "test program output (sizeof(long)): $a"
	if [ ! "$a" ] ; then
	    echo "test program failed!  Assuming 32 bits."
	    log "assuming 32 bits"
	    SIZEOF_LONG=4
	else
	    SIZEOF_LONG="$a"
	    if [ $SIZEOF_LONG -lt 4 ] ; then
		echo "`expr $SIZEOF_LONG \* 8` bits... huh?"
		cat <<EOF
    "long" must be at least 32 bits.  Please check your compiler settings.

Configuration aborted.

EOF
		exit 1
	    else
		echo `expr $SIZEOF_LONG \* 8` bits
		log "`expr $SIZEOF_LONG \* 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 >tmp/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 tmp/test.c $CC_LIBS -o tmp/test ; then
	a="`tmp/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 <<EOF
    Services requires a time_t of at least 32 bits.  Please check your system
    configuration.

Configuration aborted.

EOF
		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 >tmp/test.c <<EOT
	#include <sys/types.h>
	int main() {
	    gid_t a;
	    printf("%d", sizeof(a));
	    return 0;
	}
EOT
    if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test ; then
	a="`tmp/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

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

# 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 >tmp/test.c <<EOT
	    int main() {
		extern void strerror(void);
		strerror();
	    }
EOT
	if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test ; then
	    HAVE_STRERROR=1
	    echo "ah, strerror() is here."
	    log "using strerror()"
	else
	    HAVE_STRERROR=0
	    echo "no strerror()."
	    cat >tmp/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 tmp/test.c $CC_LIBS -o tmp/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="`tmp/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

	MODE="check_strtok    "
	TEST='	char buf1[1];
		char buf2[] = "1 2 3";
		char buf3[] = "4 5 6";
		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;
		return 0;'
	if test_function "char *" strtok "(char *, const char *)" ; then : ; else
	    MISSING="$MISSING strtok"
	    echo2 "strtok "
	fi

	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 >tmp/test.c <<EOT
	int main() {
	    extern void getrlimit(), setrlimit();
	    getrlimit();
	    setrlimit();
	}
EOT
    if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/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
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 >tmp/test.c <<EOT
	int main() { return 0; }
EOT
    if run $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test ; then : ; else
	whoa_there
    fi
    if run cp -p tmp/test$EXE_SUFFIX tmp/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 tmp/test$EXE_SUFFIX tmp/test2$EXE_SUFFIX && test -f tmp/test$EXE_SUFFIX && run cmp tmp/test$EXE_SUFFIX tmp/test2$EXE_SUFFIX ; then
	echo 'looks like "install" will work.'
	INSTALL="install"
    elif run cp -p tmp/test3$EXE_SUFFIX tmp/test$EXE_SUFFIX ; run install -c -m 500 tmp/test$EXE_SUFFIX tmp/test2$EXE_SUFFIX && test -f tmp/test$EXE_SUFFIX && run cmp tmp/test$EXE_SUFFIX tmp/test2$EXE_SUFFIX ; then
	echo 'looks like "install -c" will work.'
	INSTALL="install -c"
    elif run cp -p tmp/test3$EXE_SUFFIX tmp/test$EXE_SUFFIX ; run ginstall -m 500 tmp/test$EXE_SUFFIX tmp/test2$EXE_SUFFIX && test -f tmp/test$EXE_SUFFIX && run cmp tmp/test$EXE_SUFFIX tmp/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 tmp/testdir && test -d tmp/testdir ; then
	    echo "OK."
	    log "successful"
	else
	    echo "nope, using workaround."
	    log "failed"
	    MKDIR='$(TOPDIR)/install-script'
	fi
    fi
fi

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

MODE="check_copy_recur"
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 tmp/test*
    run echo test >tmp/test
    run cp tmp/test tmp/test2
    if run /bin/mkdir tmp/testA && run /bin/mkdir tmp/testB && run /bin/mv tmp/test2 tmp/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 tmp/testA tmp/testB/testC && run cmp tmp/testA/test2 tmp/testB/testC/test2 ; then
	echo "$CP_ALL"
	log \`"$CP_ALL' works"
    else
	log \`"$CP_ALL' doesn't work"
	run /bin/rm -rf tmp/testB/*
	if run sh -c '/bin/tar Ccf tmp/testA - . | /bin/tar Cxf tmp/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 [ "$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
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		$SIZEOF_LONG
#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_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

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

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'

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
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

TYPE_INT8=$TYPE_INT8
TYPE_INT16=$TYPE_INT16
TYPE_INT32=$TYPE_INT32
SIZEOF_INT=$SIZEOF_INT
SIZEOF_LONG=$SIZEOF_LONG
SIZEOF_TIME_T=$SIZEOF_TIME_T
MAX_TIME_T='$MAX_TIME_T'
SIZEOF_GID_T=$SIZEOF_GID_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 tmp

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

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
