dnl
dnl autoconf script for Nessus
dnl

dnl
dnl Supported options :
dnl
dnl --enable-release
dnl --enable-debug
dnl --enable-pthreads 	(experimental dont use dont use dont use!)
dnl --enable-syslog
dnl --enable-gtk
dnl --enable-unix-socket


AC_INIT(.root-dir)
AC_REVISION($Revision: 1.4.2.3 $)dnl

dnl version stuff -- jordan
save_IFS="${IFS}"
IFS=.
read NESSUS_MAJOR NESSUS_MINOR NESSUS_PATCH NESSUS_RC <VERSION
IFS="${save_IFS}"
NESSUS_DATE=\"`date '+%b %d, %Y'`\"
expr 0 + $NESSUS_MAJOR + $NESSUS_MINOR + $NESSUS_PATCH + 0 >/dev/null ||
AC_MSG_ERROR([ *** Panic: Corrupt version file])

test "x$prefix" != "xNONE" || prefix=/usr/local


dnl Set up the main lines of the config script
AC_CONFIG_HEADER(include/config.h)
AC_PREFIX_DEFAULT("/usr/local")
AC_CANONICAL_HOST
AC_LANG_C

dnl Check for several programs
AC_PROG_CC
AC_PROG_MAKE_SET
AC_PROG_INSTALL
INSTALL_DIR="$INSTALL -d"

test -n "$GCC" && CWALL="-Wall"

test "x$enable_language" = x && enable_language="english"
test "x$enable_gtk" = "x" && enable_gtk="yes"
test "x$enable_client" = "x" && enable_client="yes"


nessus_lib=-lnessus

dnl extending the search path for AC_PATH_PROG when searching for config scripts
XPATH="$DESTDIR$prefix/bin:$PATH"
	

dnl User options

AC_ARG_ENABLE(release,[  --enable-release	  set the compiler flags to -O6],
	CFLAGS="-O6")

AC_ARG_ENABLE(debug,[  --enable-debug	  set the compiler flags to -g],[
	CFLAGS="-g"; debug_flags="-DDEBUG"])

AC_ARG_ENABLE(gtk,[  --enable-gtk                 build with GTK],
        test "$enable_gtk" = "yes" && gtk_flags="-DUSE_GTK" && AC_DEFINE(USE_GTK))



###     use option --with-ssl to compile in the SSL support
ssl=""
sslcflags=""
AC_ARG_WITH(ssl,
        [  --with-ssl=[DIR]        enable SSL support using libraries in DIR],
        [with_ssl=$withval])



dnl only vanilla sed can handle long substitution lines

saveCFLAGS="$CFLAGS"

dnl Check for several headers
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_TIME
AC_HEADER_DIRENT
AC_CHECK_HEADERS(unistd.h getopt.h string.h strings.h sys/sockio.h sys/socketio.h)
AC_CHECK_HEADERS(sys/param.h netinet/tcpip.h netinet/in_systm.h)
AC_CHECK_HEADERS(netinet/ip_udp.h netinet/protocols.h sys/ioctl.h netinet/ip_icmp.h)
AC_CHECK_HEADERS(rpc/rpc.h netinet/udp.h dlfcn.h sys/un.h memory.h ctype.h errno.h)
AC_CHECK_HEADERS(sys/types.h stdlib.h stdio.h sys/filio.h pwd.h)
AC_CHECK_HEADERS(assert.h netdb.h netinet/in.h arpa/inet.h)
AC_CHECK_HEADERS(poll.h sys/poll.h netinet/ip_tcp.h fcntl.h signal.h limits.h)
AC_CHECK_HEADERS(sys/stat.h stat.h net/if.h sys/mman.h sys/resource.h dl.h)
AC_CHECK_HEADERS(pty.h termio.h termios.h sgtty.h libutil.h setjmp.h values.h)
AC_CHECK_HEADERS(locale.h)

dnl ./configure fails to determine the existence of some 
dnl headers under IRIX

case "$host" in
 *-irix*)
    AC_DEFINE(HAVE_SYS_SOCKET_H)
    AC_DEFINE(HAVE_NETINET_IP_H)
    AC_DEFINE(HAVE_NETINET_TCP_H)
    ;;
 *)
    AC_CHECK_HEADERS(sys/socket.h netinet/ip.h netinet/tcp.h)
    ;;
esac


dnl Check for several functions
AC_FUNC_ALLOCA
AC_FUNC_WAIT3
dnl wait4 is tested below
AC_CHECK_FUNCS(waitpid wait4 mmap atexit)
AC_CHECK_FUNCS(lstat memmove gettimeofday gethrtime getrusage rand)
AC_CHECK_FUNCS(strchr memcpy select poll)
AC_CHECK_FUNC(vsnprintf,AC_DEFINE(HAVE_VSNPRINTF))
AC_CHECK_FUNCS(bzero bcopy setsid rint mkstemp)
AC_CHECK_FUNCS(addr2ascii inet_neta setproctitle _exit)

dnl Check for sevral types and guess our byte ordering
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
AC_C_BIGENDIAN
AC_CHECK_TYPE(time_t,int)
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_UID_T

test "$with_ssl" = "yes" && forcessl="yes"

if test "$with_ssl" = "yes" -o -z "$with_ssl"
then
    #   He didn't specify an SSL location.  Let's look at some common
    #   directories where SSL has been found in the past and try and auto
    #   configure for SSL.  OpenSSL determination will be made later.
    #   This will screw up if an OpenSSL install is located in a later
    #   directory than an older SSLeay install, but the user should fix that
    #   anyways and he can override on the configure line.
    with_ssl=""
    for ac_dir in \
      /usr/local/ssl \
      /usr/ssl \
      /local/ssl \
      /opt/ssl \
      /usr/freeware \
      ; \
    do
        if test -d "$ac_dir" ; then
            with_ssl=$ac_dir
            break;
        fi
    done
    
   test -z "$with_ssl" && {
        for ac_dir in \
         /usr \
         /usr/local \
         /sw \
         ; \
         do 
           if test -r "$ac_dir/include/openssl/ssl.h" ; then
                with_ssl=$ac_dir
                break;
            fi
         done
        }
fi

if test -n "$with_ssl" -a "$with_ssl" != "no"
then
  AC_CHECK_LIB(dl, dlopen, withdl="-ldl")
  # With the autoconfigure above, the only time this is going to be
  # true is going to be when we could not find the headers.  If they
  # are not in system standard locations, we are going to be broken.
  if test "$with_ssl" = "yes"
  then
    # Let's just define the standard location for the SSLeay root
    with_ssl="/usr/local/ssl"
  fi
  if test -r $with_ssl/include/openssl/ssl.h
  then
    ### ssl.h found under openssl.  Use openssl configuration preferentially
    echo "Enabling OpenSSL support in $with_ssl"
    if test "$with_ssl" = "/usr"; then
        CEFLAGS="$CEFLAGS -I$with_ssl/include/openssl"
        sslcflags="-I$with_ssl/include/openssl"
    else
        CEFLAGS="$CEFLAGS -I$with_ssl/include -I$with_ssl/include/openssl"
        sslcflags="-I$with_ssl/include -I$with_ssl/include/openssl"
    fi
    ### OpenBSD comes with ssl headers
  elif test -r /usr/include/ssl/ssl.h
  then
    echo "Enabling SSLeay support in $with_ssl"
    sslcflags="-I/usr/include/ssl"
  else
    echo "Enabling SSLeay support in $with_ssl"
    sslcflags="-I$with_ssl/include"
  fi
  
  if test `uname` = "IRIX" -a "$with_ssl" = "/usr/freeware" ;
   then
    ssl="-L$with_ssl/lib32 -lssl -lcrypto $withdl"
   else
    ssl="-L$with_ssl/lib -lssl -lcrypto $withdl"
  fi
else
  with_ssl=""
  AC_ERROR(Could not find OpenSSL and OpenSSL headers on your system)
fi


test -n "$with_ssl" && {
                sslcflags="-DHAVE_SSL $sslcflags"
                AC_DEFINE(HAVE_SSL)
                test "x$use_cipher" = "xyes" -o -z "$use_cipher" && {
                        cipher_cflags="-DNESSUS_ON_SSL"
                        }
                }
                
                

test -n "$forcessl" -a -z "$with_ssl" && AC_ERROR("OpenSSL not found")



dnl this routine has been adopted from the GNU emacs20 distrubution
AC_MSG_CHECKING(for struct timeval)
AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#else
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif
#endif], [static struct timeval x; x.tv_sec = x.tv_usec;],
  [AC_MSG_RESULT(yes)
   HAVE_TIMEVAL=yes
   AC_DEFINE(HAVE_TIMEVAL)],
  [AC_MSG_RESULT(no)
   HAVE_TIMEVAL=no])


dnl Check for the number of arguments for gettimeofday (), this routine
dnl has been adopted from the GNU emacs20 distrubution
if test "x$HAVE_TIMEVAL" = xyes; then
AC_MSG_CHECKING(whether gettimeofday can't accept two arguments)
AC_TRY_LINK([
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#else
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif
#endif
  ],
  [
  struct timeval time;
  struct timezone dummy;
  gettimeofday (&time, &dummy);
],
  [AC_MSG_RESULT(no)],
  [AC_MSG_RESULT(yes)
   AC_DEFINE(GETTIMEOFDAY_ONE_ARGUMENT)])
fi


BROKEN_REGEXP=""
#
# RedHat 8.0 ships with a broken regexp library (Nessus bug#90)
#
test -f /etc/redhat-release && 
{
 cat /etc/redhat-release | egrep "(8\.0|9)" >/dev/null && BROKEN_REGEXP=y
 }
 

test -z "$BROKEN_REGEXP" &&
{
AC_MSG_CHECKING([for a working regexp implementation])
AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <regex.h>

int main()
{
  char fastmap[1 << 8];
  struct re_pattern_buffer pb;
  struct re_registers regs;
 
  pb.allocated = 8;
  pb.buffer = malloc(8);
  pb.fastmap = fastmap;
  pb.translate = 0;
  re_set_syntax(RE_SYNTAX_POSIX_EGREP);
  re_compile_pattern(".*nessus.*", strlen(".*nessus.*"), &pb);
  re_compile_fastmap(&pb);
  return re_search(&pb, 
  		"i use nessus everyday",
		strlen("i use nessus everyday"),
		0, 
  		strlen("i use nessus everyday"),
		&regs);
}
], [AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_REGEX_SUPPORT)],[AC_MSG_RESULT([no])])
}


dnl I18N Test (GNU gettext)
AC_MSG_CHECKING([GNU gettext available])
AC_TRY_COMPILE([#include <libintl.h>],
[extern int _nl_msg_cat_cntr;
extern int *_nl_domain_bindings;
int
main ()
{
  bindtextdomain ("", "");
  return (int) gettext ("") + (int) ngettext ("", "", 0) + _nl_msg_cat_cntr + *_nl_domain_bindings;
}],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_GNU_GETTEXT) gettext_flags="-DHAVE_GNU_GETTEXT"],
[AC_MSG_RESULT(no)])

dnl Define several paths


AC_PATH_X
AC_PATH_XTRA
PWDD=`pwd`	
AC_SYS_LONG_FILE_NAMES


if  test "`uname`" != "IRIX" ;
then
 AC_HAVE_LIBRARY(socket, [socket_lib="-lsocket";LIBS="-lsocket $LIBS";])
 AC_HAVE_LIBRARY(nsl, [nsl_lib="-lnsl";LIBS="-lnsl $LIBS";])
 AC_HAVE_LIBRARY(resolv, [resolv_lib="-lresolv";LIBS="-lresolv $LIBS";])
fi


AC_CHECK_LIB(c, inet_aton, AC_DEFINE(HAVE_INET_ATON))
AC_CHECK_LIB(resolv, inet_aton, AC_DEFINE(HAVE_INET_ATON))
AC_CHECK_LIB(z, compress, , AC_ERROR("libz is needed"))

dnl Check for the libraries we may want to use
AC_CHECK_LIB(dl, dlopen, [dl_lib="-ldl" ; AC_DEFINE(HAVE_DL_LIB)])
AC_CHECK_FUNCS(getopt_long snprintf)


dnl version defines have been extracted to a separate file
NESS_COMPILER="`$CC -v 2>&1 | tail -1 2>/dev/null`"
NESS_OS_NAME="`uname -s`"
NESS_OS_VERSION="`uname -r`"


dnl I prefer to compile a C program rather than trusting the env. variables...


dnl This test is from the configure.in of Unix Network Programming second
dnl edition example code by W. Richard Stevens
dnl ##################################################################
dnl Check if sockaddr{} has sa_len member.
dnl
AC_CACHE_CHECK(if sockaddr{} has sa_len member, ac_cv_sockaddr_has_sa_len,
        AC_TRY_COMPILE([
#               include <sys/types.h>
#               include <sys/socket.h>],
                [unsigned int i = sizeof(((struct sockaddr *)0)->sa_len)],
        ac_cv_sockaddr_has_sa_len=yes,
        ac_cv_sockaddr_has_sa_len=no))
if test $ac_cv_sockaddr_has_sa_len = yes ; then
        AC_DEFINE(HAVE_SOCKADDR_SA_LEN)
fi



case "$host" in
    *-freebsd*|*-bsdi*|*-netbsd*)
    AC_DEFINE(BSD_BYTE_ORDERING)
esac



case "$host" in
  *-netbsd*)
    AC_DEFINE(NETBSD)
    ;;
  *-openbsd*)
    AC_DEFINE(OPENBSD)
    ;;
  *-sgi-irix5*)
    AC_DEFINE(IRIX)
    no_libsocket=yes
    no_libnsl=yes
    if test -z "$GCC"; then
      sgi_cc=yes
    fi
    ;;
  *-sgi-irix6*)
    AC_DEFINE(IRIX)
    no_libsocket=yes
    no_libnsl=yes
    if test -z "$GCC"; then
      sgi_cc=yes
    fi
    ;;
  *-solaris2.0*)  
    AC_DEFINE(STUPID_SOLARIS_CHECKSUM_BUG)
    AC_DEFINE(SOLARIS)
    ;;
  *-solaris2.1*)
    AC_DEFINE(STUPID_SOLARIS_CHECKSUM_BUG)
    AC_DEFINE(SOLARIS)
    ;;
  *-solaris2.2*)
    AC_DEFINE(STUPID_SOLARIS_CHECKSUM_BUG)
    AC_DEFINE(SOLARIS)
    ;;
  *-solaris2.3*)
    AC_DEFINE(STUPID_SOLARIS_CHECKSUM_BUG)
    AC_DEFINE(SOLARIS)
    ;;
  *-solaris2.4*)
    AC_DEFINE(STUPID_SOLARIS_CHECKSUM_BUG)
    AC_DEFINE(SOLARIS)
    ;;
  *-solaris2.5.1)
    AC_DEFINE(STUPID_SOLARIS_CHECKSUM_BUG)
    AC_DEFINE(SOLARIS)
    ;;
  *-solaris*)
    AC_DEFINE(SOLARIS)
    ;;
  *-sunos4*)
    AC_DEFINE(SUNOS)
    AC_DEFINE(SPRINTF_RETURNS_STRING)
    no_libnsl=yes
    no_libsocket=yes
    ;;
  *-linux*)
    linux=yes
    AC_DEFINE(LINUX)
    AC_DEFINE(PCAP_TIMEOUT_IGNORED)  # libpcap doesn't even LOOK at
                                     # the timeout you give it under Linux
    ;;
  *-freebsd*)
    AC_DEFINE(FREEBSD)
    ;;
  *-bsdi*)
    AC_DEFINE(BSDI)
    ;;
esac



AC_MSG_CHECKING([whether struct sigaction has sa_restorer])
	AC_TRY_COMPILE([
#include <signal.h>],
[
 struct sigaction sa;
 
 sa.sa_restorer = 0;
]
, signal_sa_restorer=yes)

	test "x$signal_sa_restorer" = "x" && AC_MSG_RESULT([no])
	test "x$signal_sa_restorer" = "x" || AC_MSG_RESULT([yes])
	test "x$signal_sa_restorer" = "xyes" && AC_DEFINE(HAVE_SIGNAL_SA_RESTORER)

	

if test "x$enable_client" = "xyes"; then
    client=client
    client_install=client-install
else
    unset client
    unset client_install
    enable_gtk=no
fi


test "x$enable_gtk" = "xno" ||
{
pkg_modules="gtk+-2.0 >= 2.0.0"
PKG_CHECK_MODULES(GTKCONFIG, [$pkg_modules])
AC_SUBST(GTKCONFIG_CFLAGS)
AC_SUBST(GTKCONFIG_LIBS)
}

dnl only vanilla sed can handle long substitution lines
CFLAGS="$saveCFLAGS"

test -n "$ssl" -a -d /usr/kerberos && {
        sslcflags="-I/usr/kerberos/include $sslcflags"
        ssl="-L/usr/kerberos/lib $ssl"
        } 


NESSUSD_CONFDIR='${sysconfdir}'
NESSUSD_STATEDIR='${localstatedir}/nessus'
NESSUSD_SHAREDSTATEDIR='${sharedstatedir}/nessus'
NESSUSD_DATADIR='${sysconfdir}/nessus'
NESSUSD_LIBDIR='${libdir}/nessus'
NESSUSD_LOGDIR='${localstatedir}/nessus/logs'

NESSUSD_PLUGINS='${NESSUSD_LIBDIR}/plugins'
NESSUSD_REPORTS='${NESSUSD_LIBDIR}/reports'

 
man_nessus_1=doc/NessusClient.1

AC_DEFINE_UNQUOTED(NESSUSD_LANGUAGE,  "${lang}")

AC_PATH_PROG(AR, ar)
AC_SUBST(AR)
AC_SUBST(PWD)
AC_SUBST(PWDD)
AC_SUBST(CFLAGS)
AC_SUBST(CWALL)
AC_SUBST(GTK_VERSION)
AC_SUBST(NESSUS_MAJOR)
AC_SUBST(NESSUS_MINOR)
AC_SUBST(NESSUS_PATCH)
AC_SUBST(NESSUS_RC)
AC_SUBST(NESSUS_DATE)
AC_SUBST(NESS_COMPILER)
AC_SUBST(NESS_OS_NAME)
AC_SUBST(NESS_OS_VERSION)
AC_SUBST(NESSUSD_CONFDIR)
AC_SUBST(NESSUSD_STATEDIR)
AC_SUBST(NESSUSD_SHAREDSTATEDIR)
AC_SUBST(NESSUSD_DATADIR)
AC_SUBST(NESSUSD_LIBDIR)
AC_SUBST(NESSUSD_PLUGINS)
AC_SUBST(NESSUSD_REPORTS)
AC_SUBST(NESSUSD_LOGDIR)
AC_SUBST(CWALL)
AC_SUBST(INSTALL_DIR)
AC_SUBST(INSTALL)
AC_SUBST(RUN_LIBS)
AC_SUBST(resolv_lib)
AC_SUBST(socket_lib)
AC_SUBST(nsl_lib)
AC_SUBST(resolv_lib)
AC_SUBST(ssl_lib)
AC_SUBST(gtk_flags)
AC_SUBST(debug_flags)
AC_SUBST(nessus_lib)
AC_SUBST(man_nessus_1)
AC_SUBST(dl_lib)
AC_SUBST(client)
AC_SUBST(client_install)
AC_SUBST(datadir)
AC_SUBST(GTKCONFIG_CFLAGS)
AC_SUBST(GTKCONFIG_LIBS)
AC_SUBST(ac_configure_args)
AC_SUBST(ssl)
AC_SUBST(sslcflags)
AC_SUBST(installuser)
AC_SUBST(gettext_flags)


dnl And we put everything in the appropriate files
AC_OUTPUT(nessus.tmpl include/corevers.h nessusclient-mkcert doc/NessusClient.1)


chmod +x nessusclient-mkcert

exit 0
