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

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

# Create a temporary directory for our use.

if [ ! -d tmp ] ; then
	if ! mkdir tmp ; then
		res=$?
		echo "Failed to create temporary directory!  Exiting."
		exit $res
	fi
fi
if ! chmod u+rwx tmp
	res=$?
	echo "Cannot write to temporary directory!  Exiting."
	exit $res
fi
###########################################################################

# Variable initialization.

BINDEST=/usr/local/sbin
DATDEST=/usr/local/lib/services

CC=
CC_FLAGS=
CC_LIBS=

HAVE_STRICMP=
HAVE_STRCASECMP=
HAVE_STRDUP=
HAVE_WORKING_STRSPN=
HAVE_STRERROR=
HAVE_SYS_ERRLIST=

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

# Command-line parsing.

IGNORE_CACHE= ; USER_CC= ; USRE_CC_FLAGS= ; USER_CC_LIBS=
export IGNORE_CACHE USER_CC USER_CC_FLAGS USER_CC_LIBS

while [ $# -gt 1 ] ; 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" = "-libs" ] ; then
		shift
		USER_CC_LIBS=$1
	else
		if [ "$1" != "-help" ] ; then
			echo >&2 Unknown option/parameter: "$1"
		fi
		cat >&2 <<EOT
Available options:
	-ignore-cache	Don't use cache file if it exists
	-cc		Specify C compiler to use (overrides cache and check)
	-cflags		Specify compilation flags (defaults: -O2 for gcc,
			    -O for other compilers)
	-libs		Specify extra link libraries to use (default: none)
EOT
		exit 2
	fi
	shift
done

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

# 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 -z "$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
fi

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

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

export ok INPUT

####

ok=0
while [ $ok -eq 0 ] ; do
	echo 'In what directory do you want the binaries to be installed?'
	echo 'Press Return for the default, or enter a new value.'
	echo -n "[$BINDEST] "
	read INPUT
	if [ ! "$INPUT" ] ; then
		INPUT=$BINDEST
	fi
	if [ ! -d "$INPUT" ] ; then
		if [ -e "$INPUT" ] ; then
			echo "$INPUT exists, but is not a directory!"
		else
			echo "$INPUT does not exist.  Create it?"
			echo -n "[y] "
			read YN
			if [ "$YN" != "n" ] ; then
				if mkdir $INPUT ; then
					ok=1
				fi
			fi
		fi
	else
		ok=1
	fi
done
BINDEST=$INPUT

####

ok=0
while [ $ok -eq 0 ] ; do
	echo 'Where do you want the data files to be installed?'
	echo -n "[$DATDEST] "
	read INPUT
	if [ ! "$INPUT" ] ; then
		INPUT=$DATDEST
	fi
	if [ ! -d "$INPUT" ] ; then
		if [ -e "$INPUT" ] ; then
			echo "$INPUT exists, but is not a directory!"
		else
			echo "$INPUT does not exist.  Create it?"
			echo -n "[y] "
			read YN
			if [ "$YN" != "n" ] ; then
				if mkdir $INPUT ; then
					ok=1
				fi
			fi
		fi
	else
		ok=1
	fi
done
DATDEST=$INPUT

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

# Search for a compiler.

echo -n "Searching for a suitable compiler... "
if [ "$USER_CC" ] ; then
	CC="$USER_CC"
	echo "(supplied) using $CC."
elif [ "$CC" ] ; then
	echo "(cached) using $CC."
elif gcc --version >/dev/null 2>&1 ; then
	echo "great, found gcc!"
	CC=gcc
	CC_FLAGS=-O2
else
	echo "gcc not found."
	echo -n "    Looking for alternatives... "
	if cc >/dev/null 2>&1 ; then
		CC=cc
	elif c89 >/dev/null 2>&1 ; then
		CC=c89
	else
		echo "no C compiler found!"
		echo "    Use the -cc command line option to specify your C compiler."
		exit 1
	fi
	# See if it handles ANSI.
	cat >tmp/test.c <<EOT
int main(int argc, char **argv) {
	extern void foo(int bar);
}
EOT
	if $CC tmp/test.c -o tmp/test >/dev/null 2>&1 ; then
		echo "using $CC."
	else
		echo "found $CC, but it's not ANSI-compliant!"
		echo "    Use the -cc command line option to specify your C compiler."
		exit 1
	fi
	CC_FLAGS=-O
fi


# Test compiler options.

if [ "$USER_CC_FLAGS" ] ; then
	CC_FLAGS="$USER_CC_FLAGS"
	echo "Compiler flags supplied: $CC_FLAGS"
else
	echo -n "Testing default compiler flags ($CC_FLAGS)... "
	if $CC $CC_FLAGS tmp/test.c -o tmp/test ; then
		echo "looks good."
	else
		echo "no luck!  Using no flags."
		CC_FLAGS=
	fi
fi

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

# See what libraries we have that we might need.

echo -n "Let's see what libraries are lying around... "
if $CC $CC_FLAGS tmp/test.c -lnsl tmp/test ; then
	CC_LIBS="$CC_LIBS -lnsl"
	echo -n "-lnsl "
fi
if $CC $CC_FLAGS tmp/test.c -lsocket tmp/test ; then
	CC_LIBS="$CC_LIBS -lsocket"
	echo -n "-lsocket "
fi
if $CC $CC_FLAGS tmp/test.c -lbsd tmp/test ; then
	CC_LIBS="$CC_LIBS -lbsd"
	echo -n "-lbsd "
fi
echo ""
if [ "$USER_CC_LIBS" ] ; then
	CC_LIBS="$CC_LIBS $USER_CC_LIBS"
	echo "Additional user-supplied libraries: $USER_CC_LIBS"
fi

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

# Look for missing/broken built-in routines.

echo -n "How to complain when something goes wrong... "
cat >tmp/test.c <<EOT
int main() {
	extern void strerror(void);
	strerror();
}
EOT
if $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test ; then
	HAVE_STRERROR=1
	echo "ah, strerror() is here."
else
	echo "no strerror()."
	cat >tmp/test.c <<EOT
int main() {
	extern char *__sys_errlist[];
	char *s;
	s = __sys_errlist[0];
}
EOT
	if $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."
	else
		echo "    You don't have __sys_errlist either, so we'll have to make do."
	fi
fi


echo -n "Looking for other routines we need that you don't have... "

cat >tmp/test.c <<EOT
int main() {
	extern int stricmp(char *s1, char *s2);
	extern int strnicmp(char *s1, char *s2, int len);
	return stricmp("ABC","abc") == 0  ? 0 : 1;
}
EOT
if $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test && tmp/test ; then
	HAVE_STRICMP=1
else
	echo -n "str[n]icmp "
fi

cat >tmp/test.c <<EOT
int main() {
	extern char *strdup(char *s);
	char *s, *t;
	s = "ABC"; t = strdup(s);
	return (t != NULL && strcmp(s, t) == 0) ? 0 : 1;
}
EOT
if $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test && tmp/test ; then
	HAVE_STRDUP=1
else
	echo -n "strdup "
fi

cat >tmp/test.c <<EOT
int main() {
	extern char *strspn(char *s, char *tok);
	return (strspn("ABCBA", "BA") == 2 && strspn("123", "123") == 3) ? 0 : 1;
}
EOT
if $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test && tmp/test ; then
	HAVE_STRSPN=1
else
	echo -n "strspn "
fi

cat >tmp/test.c <<EOT
int main() {
	extern void strsignal(void);
	strsignal();
}
EOT
if $CC $CC_FLAGS tmp/test.c $CC_LIBS -o tmp/test ; then
	HAVE_STRSIGNAL=1
else
	echo -n "strsignal "
fi

echo ""

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

# Create files.

echo -n "Creating sysconf.h... "
cat >sysconf.h <<EOT
/*
 * This file is generated automatically by "configure".  Any changes made
 * to it will be erased next time "configure" is run.
 */

#define HAVE_STRERROR		$HAVE_STRERROR
#define HAVE_SYS_ERRLIST	$HAVE_SYS_ERRLIST
#define HAVE_STRICMP		$HAVE_STRICMP
#define HAVE_STRDUP		$HAVE_STRDUP
#define HAVE_STRSPN		$HAVE_STRSPN
#define HAVE_STRSIGNAL		$HAVE_STRSIGNAL
EOT
echo "done."

echo -n "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
EXTRA_CFLAGS=$CC_FLAGS
LIBS=$CC_LIBS

BINDEST=$BINDEST
DATDEST=$DATDEST
EOT

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

echo 'All done!  Now type "make" to compile Services.'
exit 0
