
# Require autoconf 2.13
AC_PREREQ(2.13)

dnl Process this file with autoconf to produce a configure script.
AC_INIT(nmap.c)

if test -d /usr/local/lib; then
  LDFLAGS="$LDFLAGS -L/usr/local/lib"
fi
if test -d /usr/local/include; then
  CFLAGS="$CFLAGS -I/usr/local/include"
fi

libpcapdir=libpcap-possiblymodified
AC_SUBST(libpcapdir)

dnl use config.h instad of -D macros
AC_CONFIG_HEADER(config.h)

dnl Checks for programs.
AC_PROG_CC
 if test -n "$GCC"; then
      CFLAGS="$CFLAGS -Wall "
 fi
dnl AC_PROG_INSTALL
dnl AC_PATH_PROG(MAKEDEPEND, makedepend)

AC_SUBST(COMPAT_OBJS)
AC_SUBST(COMPAT_SRCS)

dnl Host specific hacks
AC_CANONICAL_HOST

linux=no

case "$host" in
  *-netbsd*)
    AC_DEFINE(NETBSD)
    ;;
  *-openbsd*)
    AC_DEFINE(OPENBSD)
    ;;
  *-sgi-irix5*)
    AC_DEFINE(IRIX)
    if test -z "$GCC"; then
      sgi_cc=yes
    fi
    ;;
  *-sgi-irix6*)
    AC_DEFINE(IRIX)
    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)
    ;;
  *-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)
    ;;
  *-apple-darwin*)
    macosx=yes
    AC_DEFINE(MACOSX)
    ;;
esac

dnl Checks for libraries.
dnl AC_CHECK_LIB(m, pow)
dnl on Mac OSX the math library seems to contain unwanted getopt cruft
if test xx$macosx = xx; then
  AC_CHECK_LIB(m, main)
fi


dnl If any socket libraries needed
AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent))
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))

dnl need posix4/nanosleep for solaris 2.4
AC_CHECK_FUNC(nanosleep, , AC_CHECK_LIB(posix4, nanosleep))

dnl Check whether libpcap is already available
have_libpcap=no

# By default, search for pcap library
test "${with_libpcap+set}" != "set" && with_libpcap=yes

AC_ARG_WITH(libpcap,
[  --with-libpcap[=DIR]    Look for pcap include/libs in DIR],
[  case "$with_libpcap" in
  yes)
    AC_CHECK_HEADER(pcap.h,
      AC_CHECK_LIB(pcap, pcap_datalink,
      [have_libpcap=yes LIBS="-lpcap $LIBS"]))
    ;;
  *)
    _cppflags=$CPPFLAGS
    _ldflags=$LDFLAGS

    CPPFLAGS="-I$with_libpcap/include $CPPFLAGS"
    LDFLAGS="-L$with_libpcap/lib $LDFLAGS"

    AC_CHECK_HEADER(pcap.h,[
      AC_CHECK_LIB(pcap, pcap_datalink,
	[have_libpcap=yes LIBS="-lpcap $LIBS"
	LIBPCAP_INC=$with_libpcap/include
	LIBPCAP_LIB=$with_libpcap/lib])])

    LDFLAGS=$_ldflags
    CPPFLAGS=$_cppflags
    ;;
  esac]
)
if test $linux = yes; then
  have_libpcap=no
fi

if test $have_libpcap = yes; then
  if test "${LIBPCAP_INC+set}" = "set"; then
    _cflags=$CFLAGS
    _ldflags=$LDFLAGS

    CFLAGS="-I$LIBPCAP_INC $CFLAGS"
    LDFLAGS="-L$LIBPCAP_LIB $LDFLAGS"
  fi

  AC_MSG_CHECKING(if libpcap version is recent enough)
  AC_TRY_RUN([
#include <stdio.h>
extern char pcap_version[];
int main() {
  int major, minor;
  sscanf(pcap_version,"%d.%d", &major, &minor);
  if (major > 0) 
    exit(0);
  if (minor > 4)
    exit(0);
  if (minor < 4)
    exit(1);
  if (pcap_version[3] > 'a')
    exit(0);
  if (pcap_version[3] == 'a') {
    if(!sscanf(&pcap_version[4], "%d", &minor))
      exit(1);
    if (minor >= 6)
      exit(0);
    else
      exit(1);
  }
  exit(1);
}],
[AC_MSG_RESULT(yes); have_libpcap=yes],
[AC_MSG_RESULT(no); have_libpcap=no],
[AC_MSG_RESULT(no); have_libpcap=no])
fi
if test $have_libpcap = yes; then
  PCAP_DEPENDS=""
  PCAP_CLEAN=""
  PCAP_DIST_CLEAN=""
  AC_DEFINE(HAVE_LIBPCAP)
else
  if test "${LIBPCAP_INC+set}" = "set"; then
    LDFLAGS="-L$libpcapdir $_ldflags"
    CFLAGS="$_cflags -I$libpcapdir"
  else
    LDFLAGS="-L$libpcapdir $LDFLAGS"
    CFLAGS="$CFLAGS -I$libpcapdir"
  fi
  PCAP_DEPENDS='$(LIBPCAPDIR)/libpcap.a'
  PCAP_CLEAN="pcap_clean"
  PCAP_DIST_CLEAN="pcap_dist_clean"
fi

AC_SUBST(PCAP_DEPENDS)
AC_SUBST(PCAP_CLEAN)
AC_SUBST(PCAP_DIST_CLEAN)

dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(string.h getopt.h strings.h memory.h sys/param.h sys/sockio.h  netinet/if_ether.h bstring.h sys/time.h pwd.h unistd.h )
AC_HEADER_TIME

dnl Checks for typedefs, structures, and compiler characteristics.

dnl check for void should be put in
dnl AC_MSG_CHECKING(for void)
dnl AC_TRY_COMPILE(, [void *foo = 0;], 
dnl [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_VOID)], [AC_MSG_RESULT(no)])

dnl so should check for 'const'
dnl AC_MSG_CHECKING(for const)
dnl AC_TRY_COMPILE(, [const int foo = 0;], 
dnl [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_CONST)], [AC_MSG_RESULT(no)])

dnl equiv to '#define inline' to 'inline', '__inline__', '__inline' or ''
AC_C_INLINE
if test -n "$sgi_cc"; then
   AC_DEFINE(inline, )
fi

dnl AC_HEADER_TIME

AC_MSG_CHECKING([struct ip])
AC_TRY_COMPILE([#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>],
               [struct ip ip;],
               [AC_MSG_RESULT(yes); bsd_networking=yes],
               [AC_MSG_RESULT(no); bsd_networking=no]);
if test $bsd_networking = yes; then

  AC_DEFINE(BSD_NETWORKING)
  AC_MSG_CHECKING([ip_v in struct ip])
  AC_TRY_COMPILE([#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>],
                 [struct ip ip; ip.ip_v;],
                 [AC_MSG_RESULT(yes); has_bitfields=yes],
                 [AC_MSG_RESULT(no); has_bitfields=no])

  if test $has_bitfields = no; then
    SAVE_CFLAGS="$CFLAGS"
    CFLAGS="-D__STDC__=2"

    AC_MSG_CHECKING([if setting __STDC__=2 gives ip_v])
    AC_TRY_COMPILE([#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>],
                   [struct ip ip; ip.ip_v;],
                   [AC_MSG_RESULT(yes); setting_stdc_helps=yes],
                  [AC_MSG_RESULT(no); setting_stdc_helps=no])

    CFLAGS="$SAVE_CFLAGS"
    if test $setting_stdc_helps = yes; then
      CFLAGS="$CFLAGS -D__STDC__=2"
    else
      AC_MSG_RESULT(Can't figure out how to get bitfields - configure failed)
      exit 1
    fi
  fi
fi

AC_SUBST(CFLAGS)

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

dnl check endedness
AC_C_BIGENDIAN

AC_MSG_CHECKING([if struct in_addr is a wacky huge structure (some Sun boxes)])

AC_TRY_COMPILE([#include <netinet/in.h>], struct in_addr i; i._S_un._S_addr;, \
              AC_DEFINE(IN_ADDR_DEEPSTRUCT) \
              AC_MSG_RESULT(yes) , \
              AC_TRY_COMPILE([#include <sys/types.h>
#include <netinet/in.h>], struct in_addr i; i.S_un.S_addr;, \
                             AC_DEFINE(IN_ADDR_DEEPSTRUCT) \
                             AC_MSG_RESULT(yes) , \
                             AC_MSG_RESULT(no);))

AC_CACHE_CHECK(if struct icmp exists, ac_cv_struct_icmp_exists,
        AC_TRY_COMPILE([
#               include <sys/types.h>
#               include <sys/param.h>
#               include <netinet/in_systm.h>
#               include <netinet/in.h>               
#               define __USE_BSD
#               define __FAVOR_BSD
#               define __BSD_SOURCE
#               include <netinet/ip.h>
#               include <netinet/ip_icmp.h>],
                [unsigned int i = sizeof(struct icmp)],
        ac_cv_struct_icmp_exists=yes,
        ac_cv_struct_icmp_exists=no))
if test $ac_cv_struct_icmp_exists = yes ; then
        AC_DEFINE(HAVE_STRUCT_ICMP)
fi

AC_CACHE_CHECK(if struct ip exists, ac_cv_struct_ip_exists,
        AC_TRY_COMPILE([
#               include <sys/types.h>
#               include <sys/param.h>
#               include <netinet/in_systm.h>
#               include <netinet/in.h>               
#               define __USE_BSD
#               define __FAVOR_BSD
#               define __BSD_SOURCE
#               include <netinet/ip.h>],
                [unsigned int i = sizeof(struct ip)],
        ac_cv_struct_ip_exists=yes,
        ac_cv_struct_ip_exists=no))
if test $ac_cv_struct_ip_exists = yes ; then
        AC_DEFINE(HAVE_STRUCT_IP)
fi

AC_CACHE_CHECK(if struct ip has ip_sum member, ac_cv_ip_has_ip_sum,
        AC_TRY_COMPILE([
#               include <sys/types.h>
#               include <sys/param.h>
#               include <netinet/in_systm.h>
#               include <netinet/in.h>
#               define __USE_BSD
#               define __FAVOR_BSD
#               define __BSD_SOURCE
#               include <netinet/ip.h>
#               include <netinet/ip_icmp.h>],
                [unsigned int i = sizeof(((struct ip *)0)->ip_sum)],
        ac_cv_ip_has_ip_sum=yes,
        ac_cv_ip_has_ip_sum=no))
if test $ac_cv_ip_has_ip_sum = yes ; then
        AC_DEFINE(HAVE_IP_IP_SUM)
fi


dnl Checks for library functions.
dnl AC_TYPE_SIGNAL
AC_CHECK_FUNCS( bzero snprintf vsnprintf memcpy usleep nanosleep strerror strcasestr inet_aton getopt_long_only )

dnl AC_CHECK_FUNCS(gethostname gettimeofday select socket strdup strstr )

AC_ARG_WITH(libnbase,
[  --with-libnbase=DIR     Look for nbase include/libs in DIR],
[  case "$with_libnbase" in
  yes)
    ;;
  *)
    NBASEDIR="$with_libnbase"
    ;;
  esac],
NBASEDIR="nbase"
)

LDFLAGS="$LDFLAGS -L$NBASEDIR"
CFLAGS="$CFLAGS -I$NBASEDIR"
LIBS="$LIBS -lnbase"

AC_SUBST(NBASEDIR)

dnl I need to configure nmapfe and libpcap here since the user might
dnl have specified special options (such as --prefix )
dnl
dnl But I only have to configure libpcap if I am going to use it
if test $have_libpcap = yes ; then
        subdirs="$NBASEDIR nmapfe"
else
        subdirs="$NBASEDIR $libpcapdir nmapfe"
fi
AC_CONFIG_SUBDIRS( $subdirs )

dnl Configure libpcap if we need to since a lot of lamers don't
dnl already have it installed ...
dnl if test $have_libpcap = nsadf ; then
dnl    echo "Have libpcap is set to $have_libpcap ";
dnl    asdfasdf sdsdf sfd sdfsd
dnl    AC_CONFIG_SUBDIRS( $libpcapdir )
dnl fi

AC_OUTPUT(Makefile)




