#!/bin/sh
#
# Configuration script for Services.

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

# Nifty handy functions.

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

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

run () {
	echo >&3 "$MODE: >>> $*"
	$* >&3 2>&3 </dev/null
}

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 | tr '[a-z]/.-' '[A-Z]___'`"
	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 ; 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 () {
	echo ""
	echo ""
	echo "*** WHOA THERE! ***"
	echo ""
	echo "We suddenly couldn't compile using the C compiler we already tested!"
	echo "The command line we used was:"
	echo "     $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test"
	echo "Please try to fix this; if you can't, mail achurch@dragonfire.net"
	echo "with information about your system, the output from this script,"
	echo "and the "\`"configure.log' file generated by this script."
	echo ""
	exit 4
}

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

# Create a temporary directory for our use.

if [ -d 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.

PROGRAM=services
BINDEST="`pwd`/bin"
DATDEST="`pwd`/data"
SERVPATH="`pwd`"

RUNGROUP=
UMASK=
NETWORK_DOMAIN=
IRCTYPE="1"
BAHAMUT="2"
IRCTYPE_DEF=
IRCTYPE_DEF2=
IRCTYPE_DEF3=
IRCTYPE_DEF4=
IRCTYPE_DEF5=
IRCTYPE_DEF6=
IRCTYPE_DEF7=
SVSJOIN=
ALLOWUMODE=
BOTMODE=
SJOIN=
SJ3=
NICKV2=
NONSUPER=Y
NONSUPER_C=
GAMES=N
WEBSERV=N
INSTALL=
CP_ALL=

CC=
CC_FLAGS=bonkle
CC_LFLAGS=bonkle
CC_LIBS=bonkle

TYPE_INT16=
TYPE_INT32=

HAVE_SYS_SELECT_H=
HAVE_SYS_SYSPROTO_H=

HAVE_STRERROR=
HAVE_SYS_ERRLIST=0

HAVE_SNPRINTF=
BAD_SNPRINTF=
HAVE_STRICMP=
HAVE_STRCASECMP=
HAVE_STRDUP=
HAVE_STRSPN=
HAVE_STRSIGNAL=
HAVE_GETTIMEOFDAY=
HAVE_SETGRENT=
HAVE_UMASK=
HAVE_FORK=
MISSING=bonkle

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

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

IGNORE_CACHE= ; USER_CC= ; USER_CC_FLAGS=bonkle ; USER_CC_LFLAGS=bonkle
USER_CC_LIBS=
export IGNORE_CACHE USER_CC USER_CC_FLAGS USER_CC_LFLAGS USER_CC_LIBS

while [ $# -gt 0 ] ; do
	if [ "$1" = "-ignore-cache" ] ; then
		IGNORE_CACHE=bonkle
	elif [ "$1" = "-cc" ] ; then
		shift
		USER_CC=$1
	elif [ "$1" = "-cflags" ] ; then
		shift
		USER_CC_FLAGS=$1
	elif [ "$1" = "-lflags" ] ; then
		shift
		USER_CC_LFLAGS=$1
	elif [ "$1" = "-libs" ] ; then
		shift
		USER_CC_LIBS=$1
	elif [ "$1" = "-os2" ] ; then
		PROGRAM=services.exe
	else
		if [ "$1" != "-help" -a "$1" != "-h" -a "$1" != "--help" ]; then
			echo >&2 Unknown option/parameter: "$1"
			exitval=1
		else
			exitval=0
		fi
		cat >&2 <<EOT
Available options:
	-ignore-cache	Don't use cache file if it exists
	-os2		Indicate that this is an OS/2 system.
	-cc		Specify C compiler to use (overrides cache and check)
	-cflags		Specify compilation flags (defaults: -O2 for gcc,
			    -O for other compilers; overrides cache/check)
	-lflags		Specify link flags for C compiler (default: none)
	-libs		Specify extra link libraries to use (default: none)
EOT
		exit $exitval
	fi
	shift
done

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

echo ""
echo "Beginning 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
	if [ ! "$HAVE_SNPRINTF" \
			-o ! "$BAD_SNPRINTF" \
			-o ! "$HAVE_STRICMP" \
			-o ! "$HAVE_STRCASECMP" \
			-o ! "$HAVE_STRDUP" \
			-o ! "$HAVE_STRSPN" \
			-o ! "$HAVE_STRSIGNAL" ] ; then
		MISSING=bonkle
	fi
fi

###########################################################################
cd doc
cp chkgen ../
cd ..
./chkgen
rm chkgen

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

export ok INPUT
ok=0
echo " "
echo "---> Select IRCd you are using"
echo " "
echo "     *******************WORK BEST*******************"
echo "     1) Unreal"
echo "     ******************EXPERIMENTAL*****************"
echo "     2) Ultimate"
echo "     3) Liquid 8.0 (or later)"
echo "     4) RageIRCd 1.4 (or later)"
echo "     5) Bahamut"
echo "     6) DreamForge"
echo "     7) CR"
echo "     ***********************************************"

while [ $ok -eq 0 ] ; do
        echo2 "[$IRCTYPE] "
        if read INPUT ; then : ; else echo "" ; exit 1 ; fi
        if [ ! "$INPUT" ] ; then
                INPUT=$IRCTYPE
        fi
        case $INPUT in
                no\ default)
                        echo "You must specify your IRC server type in order for Services to function"
                        echo "correctly."
                        ;;

                1)
			ok2=0
                        IRCTYPE_DEF="UNREAL"
                        IRCTYPE_DEF2="IRC_DALNET"
                        IRCTYPE_DEF3="DEFHALFOP"
                        IRCTYPE_DEF4="DEFPROTECT"
                        IRCTYPE_DEF5="DEFHOSTSERV"
                        SVSJOIN="SVSJOIN \"SVSJOIN\""
                        NICKV2="NICKV2"
			SJOIN="SJOIN"
			SJ3="SJ3"
			BOTMODE="BOTMODE \"rSBq\""
                        echo " "
                        echo "Please Select Version"
			echo " "
			echo "1) 3.1.x"
			echo "2) 3.2 or greater"
                        while [ $ok2 -eq 0 ] ; do
			    echo2 "[$UNREAL] "
                            if read INPUT2 ; then : ; else echo "" ; exit 1; fi
                            if [ ! "$INPUT2" ] ; then
                                INPUT2=$UNREAL
                            fi
                            case $INPUT2 in
                                no\ default)
                                    echo "Please choose one of the options listed above."
                                    ;;
                                1)
				ALLOWUMODE="ALLOWUMODE \"GBsxwi\""
                                    ok2=1
                                    ;;
				2)
				ALLOWUMODE="ALLOWUMODE \"RGBsxwi\""
		                    IRCTYPE_DEF6="UNREAL32"
                                    ok2=1
                                    ;;
                                *)
		                    echo "Please choose one of the options listed above."
                                    ;;
                            esac
                        done
                        ok=1
                        ;;

                2)
                        IRCTYPE_DEF="ULTIMATE"
                        IRCTYPE_DEF2="IRC_DALNET"
                        IRCTYPE_DEF3="DEFHALFOP"
                        IRCTYPE_DEF5="DEFHOSTSERV"
                        IRCTYPE_DEF4="DEFPROTECT"
                        SVSJOIN="SVSJOIN \"SVSJOIN\""
			ALLOWUMODE="ALLOWUMODE \"Bsxwi\""
			BOTMODE="BOTMODE \"rbB\""
                        ok=1
                        ;;

                3)
                        IRCTYPE_DEF="LIQUID"
                        IRCTYPE_DEF3="DEFHALFOP"
                        IRCTYPE_DEF2="IRC_DALNET"
                        IRCTYPE_DEF4="DEFPROTECT"
                        SVSJOIN="SVSJOIN \"SVSJOIN\""
			ALLOWUMODE="ALLOWUMODE \"nwsxi\""
			BOTMODE="BOTMODE \"rn\""
                        ok=1
                        ;;

                4)
                        IRCTYPE_DEF="RAGEIRCD"
                        IRCTYPE_DEF2="IRC_DALNET"
                        IRCTYPE_DEF3="DEFHALFOP"
                        IRCTYPE_DEF4="DEFPROTECT"
			ALLOWUMODE="ALLOWUMODE \"Bszwi\""
			BOTMODE="BOTMODE \"rSB\""
                        ok=1
                        ;;

                5)
			ok2=0
                        IRCTYPE_DEF="BAHAMUT"
                        IRCTYPE_DEF4="BAHSJOIN"
			BOTMODE="BOTMODE \"+r\""
			ALLOWUMODE="ALLOWUMODE \"Rxi\""
                        echo " "
                        echo "Please Select Version"
			echo " "
			echo "1) 1.6.0 or Greater"
			echo "2) 1.4.7 - 1.4.8"
			echo "3) 1.0.5 - 1.4.6"
                        while [ $ok2 -eq 0 ] ; do
			    echo2 "[$BAHAMUT] "
                            if read INPUT2 ; then : ; else echo "" ; exit 1; fi
                            if [ ! "$INPUT2" ] ; then
                                INPUT2=$BAHAMUT
                            fi
                            case $INPUT2 in
                                no\ default)
                                    echo "Please choose one of the options listed above."
                                    ;;
                                1)
		                    IRCTYPE_DEF2="BAH_V 150"
                 	            IRCTYPE_DEF3="ALLOW_GLINE"
				    SJOIN="SJOIN"
                                    ok2=1
                                    ;;
				2)
		                    IRCTYPE_DEF2="BAH_V 147"
                 	            IRCTYPE_DEF3="ALLOW_GLINE"
				    SJOIN="SJOIN"
                                    ok2=1
                                    ;;
				3)
                                    ok2=1
                                    ;;
                                *)
		                    echo "Please choose one of the options listed above."
                                    ;;
                            esac
                        done
                        ok=1
                        ;;

                6)
                        IRCTYPE_DEF="IRC_DALNET"
                        SVSJOIN="SVSJOIN \"SVSJOIN\""
			ALLOWUMODE="ALLOWUMODE \"xi\""
			BOTMODE="BOTMODE \"r\""
                        ok=1
                        ;;
                7)
                        IRCTYPE_DEF="CR"
			ALLOWUMODE="ALLOWUMODE \"xi\""
			BOTMODE="BOTMODE \"r\""
                        ok=1
                        ;;

                *)
                        echo "Please enter a valid option number."
                        ;;

        esac
done
IRCTYPE=$INPUT
echo ""

####

export ok INPUT
ok=0
echo "Disable X, W, MassServ [Y/N]?"
while [ $ok -eq 0 ] ; do
        echo2 "[$NONSUPER] "
        if read INPUT ; then : ; else echo "" ; exit 1 ; fi
        if [ ! "$INPUT" ] ; then
                INPUT=$NONSUPER
        fi
        case $INPUT in
                no\ default)
                        echo "You must specify Either Yes or No"
                        ;;
                Y)
                        NONSUPER_C="YES"
                        ok=1
                        ;;
                N)
                        NONSUPER_C=""
                        ok=1
                        ;;
                y)
                        NONSUPER_C="YES"
                        ok=1
                        ;;
                n)
                        NONSUPER_C=""
                        ok=1
                        ;;

                *)
                        echo "Please enter Y or N"
                        ;;
        esac
done
NONSUPER=$INPUT

echo ""

export ok INPUT
ok=0
echo "This one make your network unstable"
echo "This option also make your services lag"
echo "Enable Game [Y/N]?"

while [ $ok -eq 0 ] ; do
        echo2 "[$GAMES] "
        if read INPUT ; then : ; else echo "" ; exit 1 ; fi
        if [ ! "$INPUT" ] ; then
                INPUT=$GAMES
        fi
        case $INPUT in
                no\ default)
                        echo "You must specify Either Yes or No"
                        ;;
                Y)
                        GAMES="YES"
                        ok=1
                        ;;
                N)
                        GAMES=""
                        ok=1
                        ;;
                y)
                        GAMES="YES"
                        ok=1
                        ;;
                n)
                        GAMES=""
                        ok=1
                        ;;

                *)
                        echo "Please enter Y or N"
                        ;;
        esac
done

echo ""

export ok INPUT
ok=0
echo "Enable WebServ? (EXPERIMENTAL) [Y/N]"

while [ $ok -eq 0 ] ; do
        echo2 "[$WEBSERV] "
        if read INPUT ; then : ; else echo "" ; exit 1 ; fi
        if [ ! "$INPUT" ] ; then
                INPUT=$WEBSERV
        fi
        case $INPUT in
                no\ default)
                        echo "You must specify Either Yes or No"
                        ;;
                Y)
                        WEBSERV="YES"
                        ok=1
                        ;;
                N)
                        WEBSERV=""
                        ok=1
                        ;;
                y)
                        WEBSERV="YES"
                        ok=1
                        ;;
                n)
                        WEBSERV=""
                        ok=1
                        ;;

                *)
                        echo "Please enter Y or N"
                        ;;
        esac
done

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

# 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"
	echo "(supplied) using $CC."
	log user supplied \`"$USER_CC'"
elif [ "$CC" ] ; then
	echo "(cached) using $CC."
	log cache supplied \`"$CC'"
elif run gcc --version ; then
	echo "great, found gcc!"
	CC=gcc
	DEF_CC_FLAGS=-O2
	log using \`gcc\'
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."
		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=-O
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 no flags
	CC_LFLAGS=""
fi

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

# See what libraries we have that we might need.

MODE="find_libs       "
echo2 "Let's see what libraries are lying around... "
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=
	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.c -lsocket -o tmp/test ; then
		CC_LIBS="$CC_LIBS -lsocket"
		echo2 "-lsocket "
	fi
	if run $CC $CC_FLAGS tmp/test.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

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

# See what sizes various types are.

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?!  Assuming short."
				log "no 16-bit type found, assuming short"
				TYPE_INT16=short
			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?!  Assuming long."
				log "no 32-bit type found, assuming long"
				TYPE_INT32=long
			fi
		fi
	else
		whoa_there
	fi
fi

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

# Look for include files that might or might not be here.
echo "Checking for presence of include files:"

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

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

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

MODE="check_strerror  "
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


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

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

	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_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='return (strspn("ABCBA","BA")==2 && strspn("123","123")==3) ? 0 : 1;'
	if test_function int strspn "(const char *, const char *)" ; then : ; else
		MISSING="$MISSING strspn"
		echo2 "strspn "
	fi

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

	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  "
	TEST="(void) setgrent(); return 0;"
	if test_function int setgrent "(void)" ; then : ; else
		MISSING="$MISSING setgrent"
		echo2 "setgrent "
	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

	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.

EOT
fi

if [ $HAVE_SNPRINTF = 0 -a $BAD_SNPRINTF = 0 ] ; then
	cat <<EOT

*** Danger Will Robinson!  Without snprintf(), Services will be vulnerable
*** to buffer overflows.  Contact your OS vendor about installing a library
*** with snprintf() on your system.  (If your system does have snprintf(),
*** check configure.log; snprintf() may be too broken to use.)

EOT
fi

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

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

if [ "$INSTALL" ] ; 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 tmp/test3 ; 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 tmp/test2 && test -f tmp/test && run cmp tmp/test tmp/test2 ; then
		echo 'looks like "install" will work.'
		if [ "$RUNGROUP" ] ; then
			INSTALL="install -g $RUNGROUP -m 750"
		else
			INSTALL="install -m 700"
		fi
	elif run cp -p tmp/test3 tmp/test ; run install -c -m 500 tmp/test tmp/test2 && test -f tmp/test && run cmp tmp/test tmp/test2 ; then
		echo 'looks like "install -c" will work.'
		if [ "$RUNGROUP" ] ; then
			INSTALL="install -c -g $RUNGROUP -m 750"
		else
			INSTALL="install -c -m 700"
		fi
	elif run cp -p tmp/test3 tmp/test ; run ginstall -m 500 tmp/test tmp/test2 && test -f tmp/test && run cmp tmp/test tmp/test2 ; then
		echo 'looks like "ginstall" will work.'
		if [ "$RUNGROUP" ] ; then
			INSTALL="ginstall -g $RUNGROUP -m 750"
		else
			INSTALL="ginstall -m 700"
		fi
	else
		echo \"install\"" doesn't seem to work."
		echo "    But we can still use cp and friends, so we'll roll our own "\"install\".
		if [ "$RUNGROUP" ] ; then
			INSTALL="./install-script -g $RUNGROUP -m 750"
		else
			INSTALL="./install-script -m 700"
		fi
	fi
	log "using: $INSTALL"
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";;
		*)     CP_ALL="/bin/cp -pr";
		       log "guessing: cp -pr";;
	esac
	if [ ! -f tmp/test2 ] ; then
		run cp tmp/test tmp/test2
	fi
	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 && run cmp tmp/testA/test2 tmp/testB/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="./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 sysconf.h... "
cat >inc/sysconf.h <<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/services"
#define SERVICES_DIR		"$DATDEST"

EOT
if [ "$RUNGROUP" ] ; then cat >>inc/sysconf.h <<EOT
#define RUNGROUP		"$RUNGROUP"
EOT
// fi
// cat >>inc/sysconf.h <<EOT
// #define DEFUMASK		$UMASK
// EOT
if [ "$NETWORK_DOMAIN" ] ; then cat >>inc/sysconf.h <<EOT
#define NETWORK_DOMAIN		"$NETWORK_DOMAIN"
EOT
fi
cat >>inc/sysconf.h <<EOT

#define $IRCTYPE_DEF
EOT
if [ "$IRCTYPE_DEF2" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $IRCTYPE_DEF2
EOT
if [ "$IRCTYPE_DEF3" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $IRCTYPE_DEF3
EOT
if [ "$IRCTYPE_DEF4" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $IRCTYPE_DEF4
EOT
if [ "$IRCTYPE_DEF5" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $IRCTYPE_DEF5
EOT
if [ "$IRCTYPE_DEF6" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $IRCTYPE_DEF6
EOT
if [ "$IRCTYPE_DEF7" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $IRCTYPE_DEF7
EOT
if [ "$SVSJOIN" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $SVSJOIN
EOT
if [ "$ALLOWUMODE" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $ALLOWUMODE
EOT
if [ "$BOTMODE" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $BOTMODE
EOT
if [ "$SJOIN" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $SJOIN
EOT
if [ "$SJ3" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $SJ3
EOT
if [ "$NONSUPER_C" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define NONSUPER
EOT
if [ "$GAMES" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define GAMES
EOT
if [ "$WEBSERV" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define WEBSERVICE
EOT
if [ "$NICKV2" ] ; then cat >>inc/sysconf.h <<EOT ; fi
#define $NICKV2
EOT
cat >>inc/sysconf.h <<EOT

typedef   signed $TYPE_INT16  int16;
typedef unsigned $TYPE_INT16 uint16;
typedef   signed $TYPE_INT32  int32;
typedef unsigned $TYPE_INT32 uint32;

#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_SNPRINTF		$HAVE_SNPRINTF
#define BAD_SNPRINTF		$BAD_SNPRINTF
#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_UMASK		$HAVE_UMASK
#define HAVE_FORK		$HAVE_FORK
#define HAVE_GETHOSTBYNAME	$HAVE_GETHOSTBYNAME
EOT
echo "done."

echo2 "Creating Makefile.inc... "
cat >Makefile.inc <<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
LFLAGS=$CC_LFLAGS
LIBS=$CC_LIBS

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

INSTALL=$INSTALL
CP_ALL=$CP_ALL
RUNGROUP=$RUNGROUP
EOT
echo "done."

cat >services.cron <<EOT
0,5,10,15,20,25,30,35,40,45,50,55 * * * * $SERVPATH/serviceschk >/dev/null 2>&1
EOT

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

# Delete the temporary directory we created.

rm -rf tmp

# Generate Version File
###########################################################################

cat <<EOT
cd inc
version.sh
cd ..
[0;1m--------------------------------------------------------------
[0;1mThanks for using Auspice Services...
[0;1mALMOST DONE!
[0;1mYou can change the option you wish to have in inc/config.h
[0;1mNow run "make install" to compile Auspice Services.
[0;1m______________________________________________________________
[0m

EOT
exit 0
