#!/bin/sh

#
# (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
#

#
# $Id: compile-src,v 1.15 1996/01/24 19:26:30 chuck Exp $
#
script_name=`basename $0`

if test "$script_name" != "$0" -a "./$script_name" != "$0" ; then
   echo This script must be executed from the top level directory 
   exit 1
fi

XPWD=`pwd`

#
# The order with which the libraries are listed is important.
# It is also a problem; to understand why consider this:
#		Library A depends (uses some functions from) library B
#		Then, B must be compiled and installed before A so that
#		A can find B's include files at the standard place.
#		But when linking the program with A and B, if B precedes A
#		then none of B's code will be included since nobody has yet
#		tried to use it (since has not been encountered yet).
#
# Our solution is to list the libraries in the order they are compiled
# and while compiling them also generate the reverse list which is the
# order they have to be linked.
#
mandatory_libs="misc sio pset xlog str"
optional_libs="pq timer"

catch_sigs="2 15"
inc=/usr/include

#
# The value of ccopt is used for setting the DEBUG makefile variable.
# Therefore, it can be used to either enable debugging support (i.e. -g),
# profiling support (i.e. -pg), or optimization support (i.e. -O)
# The default is optimization.
#
cc=
ccopt=-O
lib_defs=
xinetd_defs=

while test $# -gt 0
do
    option=$1 ; shift
    case $option in
       	-libc)
		if test $# -eq 0 ; then
			echo "Argument missing. Exiting..."
			exit 1
		fi
		libc=$1
		shift
		if test ! -r $libc ; then
			echo "File is not readable: $libc"
			exit 1
		fi
		;;

	-signals)
		if test $# -eq 0 ; then
			echo "Argument missing. Exiting..."
			exit 1
		fi
		signal_handling=$1
		shift
		;;

	-cc)
		if test $# -eq 0 ; then
			echo "Argument missing. Exiting..."
			exit 1
		fi
		cc=$1
		shift
		;;

	-ccopt)
		if test $# -eq 0 ; then
			echo "Argument missing. Exiting..."
			exit 1
		fi
		ccopt=$1
		shift
		;;

	-os)
		if test $# -eq 0 ; then
			echo "Argument missing. Exiting..."
		exit 1
		fi
		osversion=$1 ;
		shift
		;;
		
	-auto)
		autoconfig=yes
		;;

	-sf|-cf)
		if test $# -eq 0 ; then
			echo "Missing argument to $option. Exiting..."
			exit 1
		fi
					
		if test "$option" = "-sf" ; then
			v=yes
		else
			v=no
		fi

		specified_flags=yes
		flag=$1
		shift

		#
		# The first 2 lines are for xinetd.
		# The 3rd line has to do with the man pages (xinetd and libraries)
		# The rest of the lines are for the libraries
		#
		case "$flag" in
		  old_wait|no_rpc|no_termios|no_posix_types)	eval $flag=$v;;
		  no_siglist)	eval $flag=$v ;;
		  has_SB)	eval $flag=$v ;;
		  old_dir|no_ftw|no_timers|no_syslog)	eval $flag=$v;;
		  has_mmap|has_memops|has_bcopy)	eval $flag=$v;;
		  has_isatty|has_bsdtty|has_sysvtty)	eval $flag=$v;;
		  has_onexit|has_atexit)              	eval $flag=$v;;
		  *)	echo "Bad flag name: $flag. Exiting..." ; exit 1
		esac
		;;

       	-custom)
		custom=yes
		;;

	-verbose)
		verbose=yes
		;;

	-clean)
		for makes in $mandatory_libs $optional_libs
		do
			cd $XPWD/libs/src/$makes
			make clean
		done
		cd $XPWD/libs/lib
		/bin/rm -f *.a
		cd $XPWD/xinetd
		make clean
		exit 0
		;;

	#
	# THIS IS THE SCRIPT DOCUMENTATION
	#
	-help)
		cat <<EOF | more
Usage: $script_name [options]
Options:
    -libc pathname	: specifies the location of the C library
    -signals type	: type of signal handling
    -os osname		: specifies the OS name and version
    -auto		: automatic configuration
    -verbose		: display info about configuration
    -custom		: there is a custom xinetd configuration file
    -cc "cc -args"	: compiler to use (incl. options)
    -ccopt option	: option should be either -g for debugging
			  or -O for optimization
    -clean		: makes all clean

Possible arguments to -signals:
         posix, bsd, simple
Possible arguments to -os:
        sunos4, sunos5-4, sunos5, irix, ultrix4,
	bsdi1, bsdi2, freebsd2, netbsd1, linux

The -sf and -cf options set or clear flags that specify
what facilities are available from the operating system
Only one flag can be specified per -sf/-cf but these options
can be used multiple times.
Available flags:
    no_timers      : BSD-type timers are not available
    no_rpc         : system does not support RPC
    no_termios     : termios(3) is not available
    no_siglist     : sys_siglist(3) is not available
    no_ftw         : ftw(3) is not available
    no_syslog      : syslog(3) is not available
    no_posix_types : POSIX types are not available
    has_isatty     : isatty(3) is available
    has_bsdtty     : system has BSD-type tty interface
    has_sysvtty    : system has SysV-type tty interface
    has_mmap       : mmap(2) is available
    has_memops     : memops(3) functions are available
    has_bcopy      : bcopy(3) is available
    has_onexit     : onexit(3) is available
    has_atexit     : atexit(3) is available
    old_wait       : wait(2) expects a 'union wait' argument
    old_dir        : old directory(3) package
    want_SB        : system supports .SB in man pages (convert .B -> .SB)

You can use the -os option to specify an operating system
and then you can use -sf/-cf for further mods.
EOF
		exit 2
	       	;;
       	*)
		echo "Bad argument: $1. Exiting..." ; exit 1
		;;
    esac
done

if test "$autoconfig" != "" -a "$osversion" != "" ; then
	echo "Only one of -auto, -os can be specified"
	exit 1
fi

if test ! "$osversion" -a ! "$autoconfig" ; then
	cat <<EOF
I need to know the operating system you are using and the version.
I know about
    SunOS 4.x     (sunos4)
    SunOS 5.x     (sunos5-4 (x<=4))
    SunOS 5.x     (sunos5   (x>=5))
    Ultrix 4.x   (ultrix4)
    BSDI 1.x       (bsdi1)
    BSDI 2.x       (bsdi2)
    FreeBSD 2.x (freebsd2)
    NetBSD 1.x   (netbsd1)
    Linux 1.x, 2.x (linux)
    IRIX 6.x        (irix)
If your OS is among these, use the name in the parentheses, otherwise
just hit <return> and I will try to figure out how to properly
EOF
	echo -n "configure xinetd for your system --> "
	read osversion
fi

#
# This if statement checks if we have a known osversion.
# If we don't, we set the autoconfig flag.
#
install="install -c"

if test "$osversion" ; then
  autoconfig=
  case $osversion in
    ultrix4 )
	signal_handling=bsd
	sio_defs="-DHAS_MEMOPS -DHAS_ATEXIT -DHAS_ISATTY"
	;;

    sunos4 )
	signal_handling=bsd
	sio_defs="-DHAS_MMAP -DHAS_ONEXIT -DHAS_MEMOPS -DHAS_ISATTY"
	;;
    sunos5* )
	signal_handling=posix
	sio_defs="-DHAS_MMAP -DHAS_MEMOPS -DHAS_ISATTY"
	if [ $osversion = sunos5-4 ]; then
	    lib_defs="$lib_defs -I/usr/ucbinclude"
	    xinetd_defs="$xinetd_defs -I/usr/ucbinclude"
	    oslibs="-L/usr/ucblib -lucb"
        fi
	xinetd_defs="$xinetd_defs -DNO_SIGLIST -Dsolaris"
	xlibs="$xlibs -lsocket -lnsl"
	install="/usr/ucb/install -c"
	if [ -z "$cc" ]; then cc="gcc -traditional"; fi
	;;

    irix )
	signal_handling=posix
	sio_defs="-DHAS_MMAP -DHAS_ATEXIT -DHAS_BCOPY -DHAS_ISATTY"
	install="echo TODO: install -c"
	;;

    linux )
	signal_handling=posix
	sio_defs="-DHAS_MMAP -DHAS_ATEXIT -DHAS_BCOPY -DHAS_ISATTY"
	;;

    bsdi1 )
	signal_handling=posix
	sio_defs="-D__FTWX_NO_FTW -DHAS_MMAP -DHAS_ATEXIT -DHAS_BCOPY -DHAS_ISATTY"
	xinetd_defs="$xinetd_defs -DNO_TERMIOS"
	xlibs="-lrpc"; oslibs="-lcompat"
	;;
    bsdi2 )
	signal_handling=posix
	sio_defs="-D__FTWX_NO_FTW -DHAS_MMAP -DHAS_ATEXIT -DHAS_BCOPY -DHAS_ISATTY"
	xinetd_defs="$xinetd_defs"
	xlibs="-lrpc"; oslibs="-lcompat"
	if [ -z "$cc" ]; then cc="shlicc2"; fi
	;;
    freebsd2 | netbsd1 )
	signal_handling=posix
	sio_defs="-D__FTWX_NO_FTW -DHAS_MMAP -DHAS_ATEXIT -DHAS_BCOPY -DHAS_ISATTY"
	misc_xsrc="cvt.c gcvt.c"; misc_xobj="cvt.o gcvt.o"
	xinetd_defs="$xinetd_defs"
	xlibs="-lrpcsvc -lcrypt"; oslibs="-lcompat"
	;;

    * )
	echo "I don't know anything about this OS. Exiting..." ; exit 1
  esac
  lib_defs="$sio_defs $lib_defs"
else
	autoconfig=yes
fi

if [ -z "$cc" ]; then
	cc=cc
fi

#
# Get namelist of C library
#
if test "$autoconfig" ; then
    echo "Obtaining name list of C library"

    if test ! "$libc" ; then
	if test -r /lib/libc.a ; then
		libc=/lib/libc.a
	else
		if test -r /usr/lib/libc.a ; then
			libc=/usr/lib/libc.a
		else
			echo -n "Please give me the pathname of the C library -> "
			read libc
			if test ! "$libc" -o ! -r "$libc" ; then
				echo "Bad pathname. Exiting..."
				exit 1
			fi
		fi
	fi
    fi
    nmfile=/tmp/libc.nm.$$
    nm $libc > $nmfile 2>/dev/null
    if test $? -ne 0 ; then
	if test ! -s $nmfile ; then
		echo "Couldn't get the namelist of C library. Exiting..."
		rm -f $nmfile
		exit 1
	else		# name list file is not empty
		echo "WARNING: The 'nm' command returned a non-zero exit status"
		echo "WARNING: so the namelist obtained from the C library may be incomplete"
		echo "Continuing with auto-configuration"
	fi
    fi
fi

if test "$specified_flags" -o "$autoconfig" ; then
	#
	# Determine supported signal handing
	#
	if test "$autoconfig" -a ! "$signal_handling" ; then
		if test "$verbose" ; then echo "Looking for sigaction" ; fi
		found=`grep sigaction $nmfile | grep T`
		if test "$found" ; then
			signal_handling=posix
		else
			if test "$verbose" ; then echo "Looking for sigvec" ; fi
			found=`grep sigvec $nmfile | grep T`
			if test "$found" ; then 
				signal_handling=bsd
			else
				signal_handling=simple
			fi
		fi
	fi

	case "$signal_handling" in
		posix)	v= ;;
		bsd)	v="-DNO_POSIX_SIGS" ;;
		simple)	v="-DNO_POSIX_SIGS -DNO_SIGVEC" ;;
	esac
	xinetd_defs="$xinetd_defs $v"

	#
	# Check for setitimer(2)
	#
	case "$no_timers" in
		yes)	v=-DNO_TIMERS ;;
		no)	v= ;;
		*)
				if test "$autoconfig" ; then
					if test "$verbose" ; then echo "Looking for setitimer" ; fi
					found=`grep setitimer $nmfile | grep T`
					if test ! "$found" ; then v=-DNO_TIMERS ; else v= ; fi
				else
					v=
				fi
	esac
	xinetd_defs="$xinetd_defs $v"

	#
	# Check for sys_siglist
	#
	case "$no_siglist" in
		yes)	v=-DNO_SIGLIST ;;
		no)	v= ;;
		*)
				if test "$autoconfig" ; then
					if test "$verbose" ; then echo "Looking for sys_siglist" ; fi
					found=`grep sys_siglist $nmfile | grep D`
					if test ! "$found" ; then v=-DNO_SIGLIST ; else v= ; fi
				else
					v=
				fi
	esac
	xinetd_defs="$xinetd_defs $v"

	#
	# Check for RPC
	#
	case "$no_rpc" in
		yes)	v=-DNO_RPC ;;
		no)	v= ;;
		*)
				if test "$autoconfig" ; then
					if test "$verbose" ; then echo "Looking for RPC" ; fi
					found=`grep rpcent $inc/netdb.h`
					if test ! "$found" ; then v=-DNO_RPC ; else v= ; fi
				else
					v=
				fi
	esac
	xinetd_defs="$xinetd_defs $v"

	#
	# Check if this system supports the old wait
	#
	case "$old_wait" in
		yes)	v=-DOLD_WAIT ;;
		no)	v= ;;
		*)
			if test "$autoconfig" ; then
				if test "$verbose" ; then echo "Looking for WEXITSTATUS" ; fi
				found=`grep WEXITSTATUS $inc/sys/wait.h`
				if test ! "$found" ; then v=-DOLD_WAIT ; else v= ; fi
			else
				v=
			fi
	esac
	xinetd_defs="$xinetd_defs $v"

	#
	# Check for pid_t
	# 
	case "$no_posix_types" in
		yes)	v=-DNO_POSIX_TYPES ;;
		no)	v= ;;
		*)
			if test "$autoconfig" ; then
				if test "$verbose" ; then echo "Looking for pid_t" ; fi
				found=`cd $inc/sys ; grep pid_t *.h | grep typedef`
				if test ! "$found" ; then v=-DNO_POSIX_TYPES ; else v= ; fi
			else
				v=
			fi
	esac
	xinetd_defs="$xinetd_defs $v"

	#
	# Check for termios
	#
	case "$no_termios" in
		yes)	v=-DNO_TERMIOS ;;
		no)	v= ;;
		*)
			if test "$autoconfig" ; then
				if test -r $inc/sys/termios.h -o -r $inc/termios.h ; then
					v=
				else
					v=-DNO_TERMIOS
				fi
			else
				v=
			fi
	esac
	xinetd_defs="$xinetd_defs $v"

	#
	# Check for new directory types
	#
	case "$old_dir" in
		yes)	v=-DOLD_DIR ;;
		no)	v= ;;
		*)
				if test "$autoconfig" ; then
					if test -r $inc/dirent.h ; then
						v=
					else
						v=-DOLD_DIR
					fi
				else
					v=
				fi
	esac
	lib_defs="$lib_defs $v"

	#
	# Check for ftw(3)
	#
	case "$no_ftw" in
		yes)	v=-D__FTWX_NO_FTW ;;
		no)	v= ;;
		*)
				if test "$autoconfig" ; then
					if test -r $inc/ftw.h ; then 
						v=
					else
						v=-D__FTWX_NO_FTW
					fi
				else
					v=
				fi
	esac
	lib_defs="$lib_defs $v"

	#
	# Check for syslog(3)
	#
	case "$no_syslog" in
		yes)	v=-DNO_SYSLOG ;;
		no)	v= ;;
		*)
				if test "$autoconfig" ; then
					if test "$verbose" ; then echo "Looking for syslog" ; fi
					found=`grep syslog $nmfile | grep T`
					if test ! "$found" ; then v=-DNO_SYSLOG ; else v= ; fi
				else
					v=
				fi
	esac
	lib_defs="$lib_defs $v"

	#
	# Check for mmap. Since it is not required, we do not try to find
	# if the system supports it.
	#
	case "$has_mmap" in
		yes)  v=-DHAS_MMAP ;;
		*)    v= ;;
	esac
	lib_defs="$lib_defs $v"

   case "$has_onexit" in
      yes)  v=-DHAS_ONEXIT ;;
      no)   v= ;;
      *)
            if test "$autoconfig" ; then
               if test "$verbose" ; then echo "Looking for on_exit" ; fi
               found=`grep on_exit $nmfile | grep T`
               if test "$found" ; then v=-DHAS_ONEXIT ; else v= ; fi
            else
               v=
            fi
   esac
   lib_defs="$lib_defs $v"

   case "$has_atexit" in
      yes)  v=-DHAS_ATEXIT ;;
      no)   v= ;;
      *)
            if test "$autoconfig" ; then
               if test "$verbose" ; then echo "Looking for atexit" ; fi
               found=`grep atexit $nmfile | grep T`
               if test "$found" ; then v=-DHAS_ATEXIT ; else v= ; fi
            else
               v=
            fi
   esac
   lib_defs="$lib_defs $v"

   case "$has_memops" in
      yes)  v=-DHAS_MEMOPS ;;
      no)   v= ;;
      *)
            if test "$autoconfig" ; then
               if test "$verbose" ; then echo "Looking for memcpy" ; fi
               found=`grep memcpy $nmfile | grep T`
               if test "$found" ; then v=-DHAS_MEMOPS ; else v= ; fi
            else
               v=
            fi
   esac
   lib_defs="$lib_defs $v"

   case "$has_bcopy" in
      yes)  v=-DHAS_BCOPY ;;
      no)   v= ;;
      *)
            if test "$autoconfig" ; then
               if test "$verbose" ; then echo "Looking for bcopy" ; fi
               found=`grep bcopy $nmfile | grep T`
               if test "$found" ; then v=-DHAS_BCOPY ; else v= ; fi
            else
               v=
            fi
   esac
   lib_defs="$lib_defs $v"

   case "$has_isatty" in
      yes)  v=-DHAS_ISATTY ;;
      no)   v= ;;
      *)
            if test "$autoconfig" ; then
               if test "$verbose" ; then echo "Looking for isatty" ; fi
               found=`grep bcopy $nmfile | grep T`
               if test "$found" ; then v=-DHAS_ISATTY ; else v= ; fi
            else
               v=
            fi
   esac
   #
   # Since SIO cannot compile without the isatty function, if isatty is not
   # in the C library, we have to provide our own. For this, we need to know
   # if the system supports BSD or SysV tty handling.
   #
   if test ! "$osversion" -a ! "$v" ; then
      while test ! "$v"
      do
         echo "Is your OS based on System V or on BSD 4.x ? I am really"
         echo -n "interested in terminal handling. You can say sysv or bsd -->"
         read ans
         case $ans in
            sysv) v=-DHAS_SYSVTTY ;;
            bsd)  v=-DHAS_BSDTTY ;;
            *) echo "Please say either 'sysv' or 'bsd'"
         esac
      done
   fi
   lib_defs="$lib_defs $v"
fi

if test "$autoconfig" ; then
   rm -f $nmfile
fi

#
# If we know the OS, we can provide the appropriate flags for SIO
#  (which has been set in a proper osversion case, see above)
#
if [ -z "$sio_defs" ]; then
	sio_defs="$lib_defs"
fi

case "$no_timers" in
    yes) lib_names="$mandatory_libs" ;;
    *)
	case "$signal_handling" in
		posix)	lib_names="$mandatory_libs $optional_libs" ;;
		bsd)	lib_names="$mandatory_libs $optional_libs"
			lib_defs="$lib_defs -DNO_POSIX_SIGS"
			;;
		*)	lib_names="$mandatory_libs"
	esac
esac

incdir=$XPWD/libs/include
mandir=$XPWD/libs/man
libdir=$XPWD/libs/lib

# Obsolete:
# Only Suns understand .SB in man pages, so if we are not dealing with
# a Sun we replace .SB with .B
# We now convert from .B to .SB only if requested
#
case "$want_SB" in
	yes) modify_manpages=yes ;;
	no)  modify_manpages= ;;
	*)   echo -n "Convert .B -> .SB in man pages ? (if you are not sure, say no) -->"
	read x
	if test "$x" = "y" -o "$x" = "yes"; then
		modify_manpages=yes
	else
		modify_manpages=
	fi
esac

if test "$modify_manpages" ; then
	#
	# We can't take any interrupts while processing the manpages
	#
	trap 'interrupt_occured=yes' $catch_sigs

	echo "Replacing .B in library man pages with .SB (if a man page is changed"
	echo "the original will be kept by appending .orig to its name)"
	for i in $lib_names
	do
		cd $XPWD/libs/src/$i
		for i in *.3
		do
			mv $i $i.orig											# save the original
			sed 's/[.]B/.SB/' $i.orig > $i					# do the replacement
			cmp -s $i $i.orig										# are they the same ?
			if test $? -eq 0 ; then rm $i.orig ; fi		# if yes, remove the copy
		done
		if test "$interrupt_occured" = "yes" ; then
			echo "Interrupt: quiting"
			exit 1
		fi
	done

	trap $catch_sigs		# no more trapping
fi

#
# Make the libraries
# Also prepare the value of the LIBS variable in the xinetd Makefile
#
mvars="DEBUG=$ccopt MANDIR=$mandir INCLUDEDIR=$incdir LIBDIR=$libdir"
for i in $lib_names
do
	echo Making library: $i
	libs="-l$i $libs"
	cd $XPWD/libs/src/$i
	#
	# Remove the archive if it is already there; this is to avoid ld 
	# complaints that the table of contents is out of date.
	rm -f lib$i.a
	case $i in
	  sio )
	    make $mvars CC="$cc" INSTALL="$install" DEFS="$sio_defs" install;;
	  misc )
	    make $mvars CC="$cc" INSTALL="$install" DEFS="$lib_defs" \
		    MISC_XSRC="$misc_xsrc" MISC_XOBJ="$misc_xobj" install;;
	  * )
	    make $mvars CC="$cc" INSTALL="$install" DEFS="$lib_defs" install;;
	esac
	if test $? -ne 0 ; then
		echo "Failed to create library: $i"
		exit 2
	fi
done

#
# Now make xinetd
# We remove the xinetd executable, if there is one, in case the libraries
# have changed
#
cd $XPWD/xinetd
rm -f xinetd
mvars="DEBUG=$ccopt INCLUDEDIR=-I$incdir"
if test "$custom" ; then xinetd_defs="$xinetd_defs -DCUSTOMCONF" ; fi
echo make CC="$cc" $mvars "DEFS=$xinetd_defs" \
    "LIBS=$libs $xlibs" OSLIBS="$oslibs" "LDFLAGS=-L$libdir ${LDFLAGS}"
make CC="$cc" $mvars "DEFS=$xinetd_defs" \
    "LIBS=$libs $xlibs" OSLIBS="$oslibs" "LDFLAGS=-L$libdir ${LDFLAGS}"

if test $? -ne 0 ; then
	echo Failed to create xinetd
	exit 2
fi

if test "$modify_manpages" ; then

	trap 'interrupt_occured=yes' $catch_sigs

	echo "Replacing .B in xinetd man pages with .SB"
	for i in *.man
	do
		mv $i $i.orig
		sed 's/[.]B/.SB/' $i.orig > $i
		cmp -s $i $i.orig										# are they the same ?
		if test $? -eq 0 ; then rm $i.orig ; fi		# if yes, remove the copy

		if test "$interrupt_occured" = "yes" ; then
			echo "Interrupt: quiting"
			exit 1
		fi
	done
	trap $catch_sigs		# no more trapping
fi

