dnl ===================================================================
dnl configure.in
dnl by Ajay Tirumala and Mark Gates <mgates@nlanr.net>
dnl ===================================================================

AC_INIT(iperf.init)
AC_CONFIG_HEADER(config.h)

sinclude(dast.m4)
sinclude(pthread.m4)

dnl ===================================================================
dnl Check if we're on AIX.
dnl I don't want to bother with the overhead of using config.guess

host_os=`uname`
if test "$host_os" = 'AIX' ; then
  CC=xlc
  CXX=xlC
fi

dnl Check if we're on OSF1 (Digital Unix)

if test "$host_os" = 'OSF1' ; then
  AC_DEFINE(SPECIAL_OSF1_EXTERN)
fi

dnl ===================================================================
dnl Checks for compilers and other tools
dnl Several things can occur when looking for a compiler:
dnl   1) configure's cache exists, so use that compiler
dnl   2) $CC is defined, so use that compiler
dnl   3) ask, user gives one, so use that compiler
dnl   4) ask, none given, so let autoconf pick

DAST_PROG_CC()
DAST_PROG_CXX()

AC_PROG_RANLIB()

dnl ===================================================================
dnl Checks for libraries.
dnl
dnl I've found that AC_CHECK_LIB is not reliable, because it checks
dnl whether a program can compile *with* the library. On SGI, there are
dnl lots of weak import errors. Test first whether a program compiles
dnl *without* the library; only then try with the library.
dnl
dnl This form variable LIBS = -lsocket -lnsl -lpthread

dnl check for -lpthread

ACX_PTHREAD()
if test "$acx_pthread_ok" = yes; then
  AC_DEFINE(HAVE_POSIX_THREAD)
  AC_DEFINE(_REENTRANT)
fi

dnl check for -lnsl, -lsocket

DAST_CHECK_NO_LIB(nsl, gethostbyname)
DAST_CHECK_NO_LIB(socket, socket)

dnl ===================================================================
dnl Checks for header files.

AC_CHECK_HEADERS(strings.h)

dnl ===================================================================
dnl Checks for typedefs, structures

dnl these intXX_t and u_intXX_t need to be defined to be the right size.
dnl only if the right size doesn't exist, use the default.

AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)

AC_CHECK_SIZEOF(unsigned short)
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned long long)

DAST_CHECK_TYPE_SIZEOF( int16_t, [#include "headers_slim.h"], 2, short )
DAST_CHECK_TYPE_SIZEOF( int32_t, [#include "headers_slim.h"], 4, int   )
DAST_CHECK_TYPE_SIZEOF( int64_t, [#include "headers_slim.h"], 8, long  )

DAST_CHECK_TYPE_SIZEOF_UNSIGNED( u_int16_t, [#include "headers_slim.h"], 2, unsigned short )
DAST_CHECK_TYPE_SIZEOF_UNSIGNED( u_int32_t, [#include "headers_slim.h"], 4, unsigned int   )
DAST_CHECK_TYPE_SIZEOF_UNSIGNED( u_int64_t, [#include "headers_slim.h"], 8, unsigned long  )

dnl Just checking whether socklen_t is defined is (alas)
dnl not sufficient. DEC OSF/1 defines it as unsigned long,
dnl but uses int as the argument for accept (this is a bug).
dnl AIX doesn't define it, but uses size_t not int as the
dnl argument for accept.
dnl Use C++ here to get an error, not just a warning as C does.

AC_DEFUN(DAST_ACCEPT_ARG, [
  if test -z "$ac_cv_accept_arg" ; then
    AC_LANG_SAVE
    AC_LANG_CPLUSPLUS

    AC_TRY_COMPILE(
      [#include <sys/types.h>
       #include <sys/socket.h>],
      [$1 length;
       accept( 0, 0, &length );],
    ac_cv_accept_arg=$1,
    ac_cv_accept_arg=)

    AC_LANG_RESTORE
  fi
])

AC_CACHE_CHECK(3rd argument of accept, ac_cv_accept_arg, [
  dnl Try socklen_t (POSIX)
  DAST_ACCEPT_ARG(socklen_t)

  dnl Try int (original BSD)
  DAST_ACCEPT_ARG(int)

  dnl Try size_t (older standard; AIX)
  DAST_ACCEPT_ARG(size_t)

  dnl Try short (shouldn't be)
  DAST_ACCEPT_ARG(short)

  dnl Try long (shouldn't be)
  DAST_ACCEPT_ARG(long)
])

dnl Try asking the user
if test -z "$ac_cv_accept_arg" ; then
  DAST_ASK("What type is the 3rd argument of accept a pointer to?",
           ac_cv_accept_arg, int)
fi

AC_DEFINE_UNQUOTED(Socklen_t, $ac_cv_accept_arg)

DAST_CHECK_TYPE(size_t,  [#include "headers_slim.h"], unsigned int)
DAST_CHECK_TYPE(ssize_t, [#include "headers_slim.h"], int)

dnl ===================================================================
dnl Checks for library functions.
dnl inet_pton doesn't exist on Solaris, or Win32
dnl gettimeofday doesn't exist on Win32

DAST_REPLACE_FUNCS(snprintf)
DAST_REPLACE_FUNCS(inet_pton)
DAST_REPLACE_FUNCS(inet_ntop)
DAST_REPLACE_FUNCS(gettimeofday)

DAST_CHECK_FUNCS(pthread_cancel)
DAST_CHECK_FUNCS(usleep)

dnl ===================================================================
dnl Checks for compiler characteristics

AC_LANG_SAVE
AC_LANG_CPLUSPLUS
DAST_CHECK_BOOL
AC_LANG_RESTORE

AC_C_BIGENDIAN

dnl ===================================================================
dnl Check for system services

dnl from Stevens' Unix Network Programming, 2nd Edition
dnl Let's see if the system really supports multicasting.
dnl
AC_MSG_CHECKING(for multicast support)
AC_CACHE_VAL(ac_cv_multicast,
	AC_TRY_RUN([
#	include <sys/types.h>
#	include <sys/socket.h>
#	include <netinet/in.h>
	main()
	{
		int fd;
		unsigned char flag = 1;
		struct sockaddr_in foo;
		struct ip_mreq mreq;
		fd = socket(AF_INET, SOCK_DGRAM, 0);
		if (fd < 0) exit(1);
		if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
			       (void*)&flag, sizeof(flag)) < 0)
			exit(1);
		exit(0);
	}],
	ac_cv_multicast=yes,
	ac_cv_multicast=no,
	ac_cv_multicast=no))
AC_MSG_RESULT($ac_cv_multicast)
if test $ac_cv_multicast = yes ; then
	AC_DEFINE(MCAST)
fi


dnl check for IPv6
AC_MSG_CHECKING(for IPv6 headers and structures)
DAST_CHECK_IPV6()
AC_MSG_RESULT($ac_accept_ipv6)

dnl ===================================================================
dnl create Makefile and config.h
dnl remove the write property, since no one should modify those files!

DAST_OUTPUT(../Makefile.rules)
