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

dnl Checks for programs.
AC_PROG_AWK
AC_PROG_CC
AC_PROG_INSTALL

dnl Checks for header files.
AC_CHECK_HEADERS(inttypes.h stdint.h unistd.h)
AC_CHECK_HEADERS(sys/vfs.h sys/statfs.h sys/statvfs.h sys/param.h)
AC_CHECK_HEADERS(sys/mount.h,,,[[
#ifdef HAVE_SYS_PARAM_H
#  include <sys/param.h>
#endif
]])
AC_CHECK_HEADERS(arpa/inet.h sys/ioctl.h sys/time.h stdarg.h io.h)
AC_CHECK_HEADERS(netinet/in.h netdb.h arpa/nameser.h)
AC_CHECK_HEADERS(resolv.h,,,[[
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
#  include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_NAMESER_H
#  include <arpa/nameser.h>
#endif
]])

dnl Checks for typedefs, structures, and compiler characteristics.

dnl Checks for library functions.
AC_CHECK_FUNCS(snprintf vsnprintf vsyslog waitpid statvfs statfs uname)
AC_CHECK_FUNCS(daemon setsid getopt localtime_r strtoumax sigprocmask)
AC_CHECK_FUNCS(gettimeofday)
AC_SYS_LARGEFILE
AC_FUNC_FSEEKO

OPT_SRC=""

dnl Checks for libraries.
AC_CHECK_FUNC(socket)
case $ac_cv_func_socket in
 no) AC_CHECK_LIB(socket, socket) ;;
esac
AC_CHECK_FUNC(gethostbyname)
case $ac_cv_func_gethostbyname in
 no) AC_CHECK_LIB(nsl, gethostbyname) ;;
esac
AC_CHECK_FUNCS(setproctitle)
case $ac_cv_func_setproctitle in
 no) AC_CHECK_LIB(util, setproctitle, AC_DEFINE(HAVE_SETPROCTITLE) LIBS="$LIBS -lutil") ;;
esac
dnl AC_CHECK_FUNC(res_search)
case x$ac_cv_header_resolv_h in
 xyes)
  AC_MSG_CHECKING(for res_search)
  AC_TRY_LINK([
  #include <sys/types.h>
  #ifdef HAVE_NETINET_IN_H
  #  include <netinet/in.h>
  #endif
  #ifdef HAVE_ARPA_NAMESER_H
  #  include <arpa/nameser.h>
  #endif
  #include <resolv.h>
  ], [res_search(0,0,0,0,0);], AC_MSG_RESULT(yes), AC_MSG_RESULT(no); ac_cv_func_res_search=no)
  case x$ac_cv_func_res_search in
   xno) AC_MSG_CHECKING(for res_search in libresolv)
        LIBS="$LIBS -lresolv"
        AC_TRY_LINK([
  #include <sys/types.h>
  #ifdef HAVE_NETINET_IN_H
  #  include <netinet/in.h>
  #endif
  #ifdef HAVE_ARPA_NAMESER_H
  #  include <arpa/nameser.h>
  #endif
  #include <resolv.h>
  ], [res_search(0,0,0,0,0);], AC_MSG_RESULT(yes), AC_MSG_RESULT(no); AC_ERROR(no resolv library found))
       ;;
  esac

  AC_MSG_CHECKING(for ns_initparse)
  AC_TRY_LINK([
  #include <sys/types.h>
  #ifdef HAVE_NETINET_IN_H
  #  include <netinet/in.h>
  #endif
  #ifdef HAVE_ARPA_NAMESER_H
  #  include <arpa/nameser.h>
  #endif
  #include <resolv.h>
  ], [ns_initparse(0,0,0);], AC_DEFINE(HAVE_NS_INITPARSE) AC_MSG_RESULT(yes), AC_MSG_RESULT(no); ac_cv_func_ns_initparse=no)

  case x$ac_cv_func_ns_initparse in
   xno)
      AC_CHECK_MEMBERS([ns_msg._msg_ptr, ns_msg._ptr], [], [], [#include <resolv.h>])
      OPT_SRC="$OPT_SRC unix/ns_parse.c"
      ;;
  esac
  ;;
esac

AC_CHECK_SIZEOF(short, 0)
AC_CHECK_SIZEOF(int, 0)
AC_CHECK_SIZEOF(long, 0)

dnl check for socklen_t
dnl 
AC_MSG_CHECKING(for socklen_t)
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/socket.h>
#ifdef HAVE_NETDB_H
#  include <netdb.h>
#endif
], [socklen_t i], AC_DEFINE(HAVE_SOCKLEN_T) AC_MSG_RESULT(yes), AC_MSG_RESULT(no), AC_MSG_RESULT(cross-compiling. No assumptions made))

dnl check for intmax_t
dnl 
case $ac_cv_header_inttypes_h$ac_cv_header_stdint_h in
 *yes*) AC_MSG_CHECKING(for intmax_t)
      AC_TRY_COMPILE([
#ifdef HAVE_INTTYPES_H
#  include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
#  include <stdint.h>
#endif], [intmax_t i], AC_DEFINE(HAVE_INTMAX_T) AC_MSG_RESULT(yes), AC_MSG_RESULT(no), AC_MSG_RESULT(cross-compiling. No assumptions made))
      ;;
esac

dnl -------------------------------------------------------------------------
dnl Signal handling

AC_MSG_CHECKING(for reliable signals)
AC_TRY_RUN([
#include <sys/types.h>
#include <signal.h>

#ifndef SIGCHLD
# define SIGCHLD SIGCLD
#endif
#ifdef USE_SIGSET
# define signal sigset
#endif

int got;

#ifdef SIGVOID
void
#endif
hand()
{
  got++;
}

main()
{
  (void)signal(SIGCHLD, hand);
  kill(getpid(), SIGCHLD);
  kill(getpid(), SIGCHLD);
  if (got < 2)
    exit(1);
  exit(0);
}
], AC_MSG_RESULT(yes),
AC_DEFINE(SYS5SIGNALS) AC_MSG_RESULT(no),
AC_DEFINE(SYS5SIGNALS) AC_MSG_RESULT(cross-compiling. No assumptions made)
)

dnl -------------------------------------------------------------------------
dnl Check for facilitynames

AC_MSG_CHECKING(for facilitynames)
AC_TRY_COMPILE([
#include <stdio.h>
#define SYSLOG_NAMES
#include <syslog.h>
], [
  return facilitynames[0].c_name && facilitynames[0].c_val;
], AC_DEFINE(HAVE_FACILITYNAMES) AC_MSG_RESULT(yes),
AC_MSG_RESULT(no),
AC_MSG_RESULT(cross-compiling. No assumptions made)
)

dnl -------------------------------------------------------------------------
dnl Check for TIOCNOTTY

AC_MSG_CHECKING(for TIOCNOTTY)
AC_TRY_COMPILE([
#include <sys/ioctl.h>
], [
  return ioctl(0, TIOCNOTTY, (char*)0);
], AC_DEFINE(HAVE_TIOCNOTTY) AC_MSG_RESULT(yes),
AC_MSG_RESULT(no),
AC_MSG_RESULT(cross-compiling. No assumptions made)
)

dnl -------------------------------------------------------------------------
dnl Check for MSG_NOSIGNAL

AC_MSG_CHECKING(for MSG_NOSIGNAL)
AC_TRY_COMPILE([
#include <sys/types.h>
#include <sys/socket.h>
], [
  return MSG_NOSIGNAL;
], AC_DEFINE(HAVE_MSG_NOSIGNAL) AC_MSG_RESULT(yes),
AC_MSG_RESULT(no),
AC_MSG_RESULT(cross-compiling. No assumptions made)
)

dnl -------------------------------------------------------------------------
dnl Optional features

AC_ARG_WITH(https, [],
            do_proxy=yes, do_proxy=no)

AC_ARG_WITH(debug,
            [  --with-debug[[=nofork]]   produce debug info (default no)],
            do_debug=$withval, do_debug=no)

AC_ARG_WITH(warn,
            [  --with-warn[[=level]]     print gcc compilation warnings
                          no|yes|full|pedantic (default yes)],
            do_warn=$withval, do_warn=yes)


AC_ARG_WITH(proxy,
            [  --with-proxy            https and socks proxy support (default no)],
            do_proxy=yes, do_proxy=no)

AC_ARG_WITH(ntlm,
            [  --with-ntlm             NTLM proxy authorization support (default no)],
            do_ntlm=yes; do_proxy=yes, do_ntlm=no)

AC_ARG_WITH(af_force,
            [  --with-af-force         Enable soft AF force feature (default no)],
            do_afforce=yes, do_afforce=no)

case x$do_proxy in
  xyes)
   AC_DEFINE(HTTPS)
   OPT_SRC="$OPT_SRC https.c"
   ;;
esac

case x$do_ntlm in
  xyes)
   AC_DEFINE(NTLM)
   OPT_SRC="$OPT_SRC ntlm/des_enc.c ntlm/helpers.c ntlm/ecb_enc.c ntlm/md4_dgst.c ntlm/set_key.c"
   ;;
esac

case x$do_afforce in
  xyes)
   AC_DEFINE(AF_FORCE)
   ;;
esac

case x$do_debug in
  xyes)
   CFLAGS="-g -DDEBUG $CFLAGS"
   ;;
  xno)
   CFLAGS="-O2 $CFLAGS"
   ;;
  xnofork)
   CFLAGS="-g -DDEBUG -DDEBUGCHILD $CFLAGS"
   ;;
  *)
   AC_MSG_WARN([Unknown debug option $do_debug ignored])
   ;;
esac

case x$do_warn in
  xyes)
   CFLAGS="-Wall -Wno-char-subscripts $CFLAGS"
   ;;
  xno)
   ;;
  xfull)
   CFLAGS="-Wall -Wno-char-subscripts -W -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmissing-noreturn -Wmissing-format-attribute -Wredundant-decls -Wnested-externs -Wunreachable-code -Waggregate-return -Wpointer-arith -Wshadow -Wundef -Wfloat-equal $CFLAGS"
   ;;
  xpedantic)
   CFLAGS="-pedantic -W $CFLAGS"
   ;;
  *)
   CFLAGS="-Wall -Wno-char-subscripts $CFLAGS"
   AC_MSG_WARN([Unknown warn option $do_warn ignored])
   ;;
esac


AC_ARG_WITH(aso,
            [  --with-aso              Amiga Style Outbound (ASO) support (default no)],
            [ test "x$withval" = "xyes" && AC_DEFINE(AMIGADOS_4D_OUTBOUND)])

AC_ARG_WITH(bwlim,
            [  --with-bwlim            Bandwidth limiting support (default no)],
            [ test "x$withval" = "xyes" && AC_DEFINE(BW_LIM)])

AC_ARG_WITH(perl,
            [  --with-perl             Perl hooks (default no)],
            [ do_perl=$withval])

case x$do_perl in
  xyes)
   AC_PATH_PROG(PERL, perl, perl)
   AC_MSG_CHECKING(for libperl)
   PERLDIR=`$PERL -MConfig -e 'print $Config{archlib}' 2>/dev/null`
   if PERLCOPT=`$PERL -MExtUtils::Embed -e ccopts 2>/dev/null`
   then
     PERLLOPT=`$PERL -MExtUtils::Embed -e ldopts`
     case x$PERLDIR in
       x)
         AC_MSG_RESULT(yes)
         ;;
       *)
         AC_MSG_RESULT($PERLDIR)
         ;;
     esac
   else
     case x$PERLDIR in
       x)
         AC_MSG_RESULT(no)
         ;;
       *)
         PERLCOPT="-I $PERLDIR/CORE -Dbool=char -DHAS_BOOL"
         PERLLOPT="$PERLDIR/auto/DynaLoader/DynaLoader.a -L$PERLDIR/CORE -lperl -ldl -lcrypt -lm"
         AC_CHECK_LIB(dl, main, PERLLOPT="$PERLLOPT -ldl")
         AC_CHECK_LIB(crypt, main, PERLLOPT="$PERLLOPT -lcrypt")
         AC_CHECK_LIB(m, main, PERLLOPT="$PERLLOPT -lm")
         AC_CHECK_LIB(socket, main, PERLLOPT="$PERLLOPT -lsocket")
         AC_MSG_RESULT($PERLDIR)
         ;;
     esac
   fi
   case x$PERLCOPT in
     x)
       ;;
     *)
       AC_MSG_CHECKING(for working libperl)
       OLD_LIBS=$LIBS
       OLD_CFLAGS=$CFLAGS
       LIBS="$LIBS $PERLLOPT"
       CFLAGS="$CFLAGS $PERLCOPT"
       AC_TRY_RUN([
          #include <EXTERN.h>
          #include <perl.h>
          #include <XSUB.h>
          int main(int argc, char** argv, char** env) {
            return perl_alloc() ? 0 : 1;
          }],
        AC_DEFINE(WITH_PERL) AC_MSG_RESULT(yes); OPT_SRC="$OPT_SRC perlhooks.c"; WITH_PERL=yes,
        AC_MSG_RESULT(no); CFLAGS=$OLD_CFLAGS; LIBS=$OLD_LIBS,
        AC_MSG_RESULT(cross-compiling. No assumptions made); CFLAGS=$OLD_CFLAGS; LIBS=$OLD_LIBS
       )
       case x$WITH_PERL in
         xyes)
           AC_MSG_CHECKING(for perl multiplicity)
           AC_TRY_RUN([
              #include <EXTERN.h>
              #include <perl.h>
              #include <XSUB.h>
              int main(int argc, char** argv, char** env) {
                PerlInterpreter *one_perl, *two_perl;
                int i1=0, i2=0;
                SV *sv;
                char *one_args[] = { "one_perl",  "-e", "\$_=1", NULL };
                char *two_args[] = { "two_perl",  "-e", "\$_=2", NULL };
                PERL_SYS_INIT3(&argc,&argv,&env);
                one_perl = perl_alloc();
                perl_construct(one_perl);
                perl_parse(one_perl, NULL, 3, one_args, (char **)NULL);
                two_perl = perl_alloc();
                PERL_SET_CONTEXT(two_perl);
                perl_construct(two_perl);
                perl_parse(two_perl, NULL, 3, two_args, (char **)NULL);
                PERL_SET_CONTEXT(one_perl);
                perl_run(one_perl);
                if ((sv = perl_get_sv("_", FALSE))) i1 = SvIV(sv);
                PERL_SET_CONTEXT(two_perl);
                perl_run(two_perl);
                if ((sv = perl_get_sv("_", FALSE))) i2 = SvIV(sv);
                PERL_SET_CONTEXT(one_perl);
                perl_destruct(one_perl);
                perl_free(one_perl);
                PERL_SET_CONTEXT(two_perl);
                perl_destruct(two_perl);
                perl_free(two_perl);
                PERL_SYS_TERM();
                return (i1==1 && i2==2 ? 0 : 1);
              }],
            AC_DEFINE(PERL_MULTIPLICITY) AC_MSG_RESULT(yes),
            AC_MSG_RESULT(no),
            AC_MSG_RESULT(cross-compiling. No assumptions made)
           )
           ;;
       esac
       ;;
   esac
   ;;
esac

AC_ARG_WITH(zlib,
            [  --with-zlib[[=path]]      zlib compression (default auto)],
            [do_zlib=$withval], 
            [do_zlib=auto])

if test ".$do_zlib" != ".no" ; then
	AC_MSG_CHECKING(for libz)
	save_LIBS="$LIBS"
	save_CFLAGS="$CFLAGS"
	found_zlib=no

	if test ".$do_zlib" = ".yes" -o ".$do_zlib" = ".auto"; then
	  zlib_paths="/usr /usr/local /usr/local/zlib"
	else
	  zlib_paths="$do_zlib"
	fi

	for zlib_path in $zlib_paths ; do
	  if test ! -d "$zlib_path/lib" ; then
	    continue
	  fi
	  if test "$zlib_path" = "/usr" ; then
	    LIBS="-lz $save_LIBS"
	    CFLAGS="$save_CFLAGS"
	  else
	    LIBS="-L$zlib_path/lib -lz $save_LIBS"
	    CFLAGS="-I$zlib_path/include $save_CFLAGS"
	  fi
	  AC_TRY_LINK(
[
#include <zlib.h>
#ifdef __cplusplus
  extern "C"
#endif
],
[
  compress2(0, (unsigned long*) 0, "", 0, 6);
  uncompress(0, (unsigned long*) 0, "", 0);
],
	    found_zlib="$zlib_path", found_zlib=no
	  )
	  if test ".$found_zlib" != ".no"; then
	    break
	  fi
	done

	if test ".$found_zlib" != ".no"; then
	  AC_MSG_RESULT(yes: $found_zlib)
	  AC_DEFINE(WITH_ZLIB)
          if test ".$compress_inc." != ".yes." ; then
            OPT_SRC="$OPT_SRC compress.c"
            compress_inc=yes
          fi
	else
	  AC_MSG_RESULT(no)
	  LIBS="$save_LIBS"
	  CFLAGS="$save_CFLAGS"
	  if test ".$do_zlib" != ".auto"; then
	    AC_ERROR(zlib not found in $zlib_paths)
	  fi
	fi
fi

AC_ARG_WITH(bzip2,
            [  --with-bzip2[[=path]]     bzip2 compression (default auto)],
            [do_bzip2=$withval], 
            [do_bzip2=auto])

if test ".$do_bzip2" != ".no" ; then
	AC_MSG_CHECKING(for libbz2)
	save_LIBS="$LIBS"
	save_CFLAGS="$CFLAGS"
	found_bzlib2=no

	if test ".$do_bzip2" = ".yes" -o ".$do_bzip2" = ".auto"; then
	  bzlib2_paths="/usr /usr/local /usr/local/bzlib2"
	else
	  bzlib2_paths="$do_bzip2"
	fi

	for bzlib2_path in $bzlib2_paths ; do
	  if test ! -d "$bzlib2_path/lib" ; then
	    continue
	  fi
	  if test "$bzlib2_path" = "/usr" ; then
	    LIBS="-lbz2 $save_LIBS"
	    CFLAGS="$save_CFLAGS"
	  else
	    LIBS="-L$bzlib2_path/lib -lbz2 $save_LIBS"
	    CFLAGS="-I$bzlib2_path/include $save_CFLAGS"
	  fi
	  AC_TRY_LINK(
[
#include <stdio.h>
#include <bzlib.h>
#ifdef __cplusplus
  extern "C"
#endif
],
[
  BZ2_bzBuffToBuffCompress(0, (unsigned long*) 0, "", 0, 6, 0, 0);
  BZ2_bzBuffToBuffDecompress(0, (unsigned long*) 0, "", 0, 0, 0);
],
	    found_bzlib2="$bzlib2_path", found_bzlib2=no
	  )
	  if test ".$found_bzlib2" != ".no"; then
	    break
	  fi
	done

	if test ".$found_bzlib2" != ".no"; then
	  AC_MSG_RESULT(yes: $found_bzlib2)
	  AC_DEFINE(WITH_BZLIB2)
          if test ".$compress_inc." != ".yes." ; then
            OPT_SRC="$OPT_SRC compress.c"
            compress_inc=yes
          fi
	else
	  AC_MSG_RESULT(no)
	  LIBS="$save_LIBS"
	  CFLAGS="$save_CFLAGS"
	  if test ".$do_bzip2" != ".auto"; then
	    AC_ERROR(bz2 lib not found in $bzlib2_paths)
	  fi
	fi
fi

AC_ARG_WITH(pthreads,
            [  --with-pthreads         Use posix threads (default no, not recommended)],
            [ with_pthreads=$withval])
case x$with_pthreads in
  xyes)
     # TODO: check if posix threads and semaphores work good
     AC_DEFINE(WITH_PTHREADS)
     AC_DEFINE(HAVE_THREADS)
     OPT_SRC="$OPT_SRC unix/sem.c"
     AC_CHECK_FUNCS(clock_gettime)
     case x$ac_cv_func_clock_gettime in
       xyes)
           AC_DEFINE(HAVE_CLOCK_GETTIME)
           ;;
       *)  AC_CHECK_LIB(rt, clock_gettime, AC_DEFINE(HAVE_CLOCK_GETTIME) LIBS="$LIBS -lrt")
           ;;
     esac

     AC_MSG_CHECKING(for gettid syscall)
     AC_TRY_RUN([
        #include <sys/syscall.h>
        #include <unistd.h>
        int main() {
          if (syscall(SYS_gettid) == -1)
            return 1;
          else
            return 0;
        }
     ], AC_DEFINE(HAVE_GETTID) AC_MSG_RESULT(yes),
       AC_MSG_RESULT(no),
       AC_MSG_RESULT(cross-compiling. No assumptions made)
     )
     ;;
esac

case $ac_cv_func_getopt in
 no) OPT_SRC="$OPT_SRC getopt.c"
     ;;
esac

case $ac_cv_func_vsnprintf$ac_cv_func_vsnprintf in
 *no*) OPT_SRC="$OPT_SRC snprintf.c"
     ;;
esac

case x$ac_cv_header_resolv_h in
 xyes) OPT_SRC="$OPT_SRC srv_gai.c"
     ;;
esac

extrasub=s%@OPT_SRC@%$OPT_SRC%g

dnl -------------------------------------------------------------------------

AC_OUTPUT(Makefile)
