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

package="pdnsd"
version=`cut -d - -f 1  "$srcdir"/version`
fullversion=`cat "$srcdir"/version`
packagerelease=`cut -d - -f 2- "$srcdir"/version`

distribution="Generic"
target="autodetect"
cachedir="/var/cache/$package"
ipv4_default=1
have_ipv4="yes"
#newrrs="yes"
query_m="udponly"
have_tcp_server="yes"
adisc="default"
slock="no";
def_id="nobody"
#have_rcsids="no"
udp_queries="yes"
tcp_queries="yes"
tempdir="/tmp"
randomdev=default
freebsd_pthread="4"
specbuild=no
threadlib=default

AM_INIT_AUTOMAKE($package, $version, [no-define])
AM_CONFIG_HEADER(config.h)
AC_GNU_SOURCE
AC_DEFINE_UNQUOTED(VERSION,"$fullversion")
AC_SUBST(fullversion)
AC_SUBST(packagerelease)

AC_ARG_WITH(distribution,
[  --with-distribution=distro  Specify target distribution (default=Generic;
                              others: RedHat, SuSE, Debian, ArchLinux)],
  distribution=$withval)
AC_SUBST(distribution)

AC_ARG_WITH(target,
[  --with-target=platform      Change compilation target platform (default: 
                              autodetect; others: Linux, BSD, Cygwin)],
  target=$withval)
case $target in
  Linux|linux)
    AC_DEFINE(TARGET, TARGET_LINUX)
    target="Linux"
    ;;
  BSD| bsd)
    AC_DEFINE(TARGET, TARGET_BSD)
    target="BSD"
    ;;
  Cygwin|CYGWIN|cygwin)
    AC_DEFINE(TARGET, TARGET_CYGWIN)
    target="cygwin"
    ;;
  autodetect)
    ;;
  *)
    AC_MSG_ERROR([--with-target must have Linux, BSD or Cygwin as parameter.])
    ;;
esac

AC_ARG_ENABLE(isdn,
[  --enable-isdn               Enable ISDN support (may cause problems on 
                              some systems; only for Linux)],
  test $enableval = "yes" && AC_DEFINE(ISDN_SUPPORT))

AC_ARG_ENABLE(ipv4,
[  --disable-ipv4              Disable IPv4 networking support 
                              (default=enabled)],
  have_ipv4=$enableval)

test $have_ipv4 = "yes" && AC_DEFINE(ENABLE_IPV4)

AC_ARG_ENABLE(ipv6,
[  --enable-ipv6               Enable IPv6 networking support],
[ if test $enableval = "yes" ; then
    AC_DEFINE(ENABLE_IPV6)
    if test $have_ipv4 != "yes" ; then
      ipv4_default=0
    fi
  fi])

AC_ARG_ENABLE(ipv4-startup,
[  --disable-ipv4-startup      Disable IPv4 on pdnsd startup by default
                              (default=enabled)],
[ if test $enableval = "yes" ; then
    ipv4_default=1
  else
    ipv4_default=0
  fi])

AC_ARG_ENABLE(ipv6-startup,
[  --enable-ipv6-startup       Enable IPV6 on pdnsd startup by default
                              (default=IPv4)],
[ if test $enableval = "yes" ; then
    ipv4_default=0
  else
    ipv4_default=1
  fi])

AC_DEFINE_UNQUOTED(DEFAULT_IPV4, $ipv4_default)

AC_ARG_ENABLE(udp-queries,
[  --disable-udp-queries       Disable udp as query method.],
  udp_queries=$enableval)

AC_ARG_ENABLE(tcp-queries,
[  --disable-tcp-queries       Disable tcp as query method.],
  tcp_queries=$enableval)

AC_ARG_WITH(query-method,
[  --with-query-method=qm      Specify the query method (default=udponly;
                              others: tcponly, tcpudp, udptcp)],
  query_m=$withval)
case $query_m in
  udponly|UDPonly)
    AC_DEFINE(M_PRESET, UDP_ONLY)
    udp_queries=yes;
    ;;
  tcponly|TCPonly)
    AC_DEFINE(M_PRESET, TCP_ONLY)
    tcp_queries=yes;
    ;;
  tcpudp|TCPUDP)
    AC_DEFINE(M_PRESET, TCP_UDP)
    udp_queries=yes;
    tcp_queries=yes;
    ;;
  udptcp|UDPTCP)
    AC_DEFINE(M_PRESET, UDP_TCP)
    udp_queries=yes;
    tcp_queries=yes;
    ;;
  *)
    AC_MSG_ERROR([--with-query-method must have udponly, tcponly, tcpudp or udptcp as parameter.])
    ;;
esac

test $udp_queries != "yes" && AC_DEFINE(NO_UDP_QUERIES)
test $tcp_queries != "yes" && AC_DEFINE(NO_TCP_QUERIES)

AC_ARG_ENABLE(tcp-server,
[  --disable-tcp-server        Disable the TCP serving ability of pdnsd],
  have_tcp_server=$enableval)

test $have_tcp_server != "yes" && AC_DEFINE(NO_TCP_SERVER)

AC_ARG_ENABLE(src-addr-disc,
[  --disable-src-addr-disc     Disable the UDP source address discovery],
    adisc=$enableval)

AC_ARG_ENABLE(socket-locking,
[  --enable-socket-locking     Enable the UDP socket locking],
    slock=$enableval)

test $slock = "yes" && AC_DEFINE(SOCKET_LOCKING)

AC_ARG_ENABLE(poll,
[  --disable-poll              Disable poll(2) and use select(2)
                              (default=enabled)],
   test $enableval != "yes" && AC_DEFINE(NO_POLL))

AC_ARG_ENABLE(new-rrs,
[  --disable-new-rrs           Disable new DNS RR types (obsolete, currently ignored)],
   newrrs=$enableval)

AC_ARG_ENABLE(strict-rfc2181,
[  --enable-strict-rfc2181     Enforce strict RFC 2181 compliance],
   test $enableval = "yes" && AC_DEFINE(RFC2181_ME_HARDER))

AC_ARG_WITH(random-device,
[  --with-random-device=device Specify random device other than 
                              /dev/random; default: C Library random() PRNG;
                              special value arc4random for BSD C Library
                              arc4random function (default on FreeBSD)],
   randomdev=$withval)

if test "$randomdev" = arc4random ; then
	AC_DEFINE(R_ARC4RANDOM)
elif test "$randomdev" = random ; then
	AC_DEFINE(R_RANDOM)
elif test "$randomdev" = default ; then
	AC_DEFINE(R_DEFAULT)
else
	AC_DEFINE_UNQUOTED(RANDOM_DEVICE, "$randomdev")
fi

AC_ARG_ENABLE(underscores,
[  --enable-underscores        Allow _ in domain names (obsolete, currently ignored)],
   underscores=$enableval)

AC_ARG_WITH(default-id,
[  --with-default-id=id        Specify default uid/gid for pdnsd 
                              (default=nobody)],
  def_id=$withval)
AC_SUBST(def_id)

AC_ARG_WITH(debug,
[  --with-debug=level          Specify debugging level (0 means no debug support)],
  AC_DEFINE_UNQUOTED(DEBUG, $withval))

AC_ARG_WITH(verbosity,
[  --with-verbosity=level      Specify default message verbosity],
  AC_DEFINE_UNQUOTED(VERBOSITY, $withval))

AC_ARG_WITH(hash-buckets,
[  --with-hash-buckets=num     Number of hash buckets to use (default=1024).
                              The number actually used is the smallest power of two
                              greater or equal to the number specified here.],
  powof2=1
  hashsz=0

  while test $powof2 -lt "$withval"
  do
    powof2=`expr 2 '*' $powof2`
    hashsz=`expr $hashsz '+' 1`
  done
  AC_DEFINE_UNQUOTED(HASH_SZ, $hashsz)
)

AC_ARG_ENABLE(hash-debug,
[  --enable-hash-debug         Debug hash tables (warning: massive output)],
  test $enableval = "yes" && AC_DEFINE(DEBUG_HASH))

AC_ARG_ENABLE(rcsids,
[  --enable-rcsids             Enable RCS IDs in executables (obsolete, currently ignored)],
  have_rcsids=$enableval)

AC_ARG_WITH(tcp-qtimeout,
[  --with-tcp-qtimeout=secs    Specify default tcp query timeout (default=30)],
  AC_DEFINE_UNQUOTED(TCP_TIMEOUT, $withval))

AC_ARG_ENABLE(tcp-subseq,
[  --enable-tcp-subseq         Enable multiple dns querys using one
                              tcp connection],
  test $enableval = "yes" && AC_DEFINE(TCP_SUBSEQ))

AC_ARG_WITH(par-queries,
[  --with-par-queries=num      Specify default parallel query number (default=2)],
  AC_DEFINE_UNQUOTED(PAR_QUERIES, $withval))

AC_ARG_WITH(max-nameserver-ips,
[  --with-max-nameserver-ips=num      Specify maximum number of IP addresses used per nameserver obtained from NS records (default=3)],
  AC_DEFINE_UNQUOTED(MAXNAMESERVIPS, $withval))

AC_ARG_ENABLE(specbuild,
[  --enable-specbuild          Only used when building pdnsd from spec files],
  specbuild=$enableval)

AC_SUBST(specbuild)

AC_ARG_WITH(thread-lib,
[  --with-thread-lib=lib       Specify thread library, overriding automatic detection (for Linux only).
                              Possible values: LinuxThreads,
                              LinuxThreads2 (implements a fix for newer glibcs)
                              or NPTL (Native POSIX Thread Library)],
  threadlib=$withval)

AC_SUBST(threadlib)

dnl Checks for programs.
AC_PROG_CC
AM_PROG_CC_STDC
AM_PROG_CC_C_O
AC_PROG_INSTALL

dnl For dbm subsystem libraries
AC_PROG_RANLIB

if test "$target" = "autodetect" ; then
  AC_MSG_CHECKING([for autodetect build target])
  uname_sys=`uname`
  if test $? -ne 0 ; then
    AC_MSG_RESULT([failed])
    AC_MSG_ERROR([uname failed or was not found in path])
  else
    case "${uname_sys}" in
    Linux)
      AC_MSG_RESULT(Linux)
      AC_DEFINE(TARGET, TARGET_LINUX)
      target="Linux"
      ;;
    FreeBSD|NetBSD|OpenBSD|Darwin)
      AC_MSG_RESULT("${uname_sys}")
      AC_DEFINE(TARGET, TARGET_BSD)
      target="BSD"
      ;;
    CYGWIN*)
      AC_MSG_RESULT("${uname_sys}")
      AC_DEFINE(TARGET, TARGET_CYGWIN)
      target="cygwin"
      ;;
    *)
      AC_MSG_RESULT([failed])
      AC_MSG_ERROR(
[Your system type could not be identified. Try setting it manually using 
--with-target])
      ;;
    esac
  fi
fi

#if test "$target" = BSD ; then
#  uname_sys=`uname`
#  if test "$uname_sys" = FreeBSD ; then
#    AC_MSG_CHECKING([for FreeBSD version])
#    osrel=`sysctl -n kern.osreldate`
#    if test $osrel -ge 500016 ; then
#      AC_MSG_RESULT([5.0 (>= 500016)])
#      freebsd_pthread="5"
#    else
#      AC_MSG_RESULT([<=5.0 (< 500016)])
#      freebsd_pthread="4"
#    fi
#  fi
#fi

if test "$adisc" = "default"; then
  if test "$target" = "cygwin" ; then
# Don't do UDP source address discovery on Cygwin platform by default.
    adisc="no"
  else
    adisc="yes"
  fi
fi

test "$adisc" = "yes" && AC_DEFINE(SRC_ADDR_DISC)


dnl Checks for libraries.
if test "$target" = "Linux"; then
AC_MSG_CHECKING([if we can compile and link with -pthread])
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -pthread"
AC_LINK_IFELSE([
#include <pthread.h>

void *thread_func(void *data)
{
	*((int *)data)=1;
	return data;
}

int main()
{
	pthread_t thread;
	void *retval;
	int val;

	if(pthread_create(&thread, NULL, thread_func, &val))
		return 1;

	if(pthread_join(thread,&retval))
		return 1;

	return (*((int *)retval)!=1);
}
],
  gcc_pthread_flag="yes", gcc_pthread_flag="no")
CFLAGS="$old_CFLAGS"
AC_MSG_RESULT([$gcc_pthread_flag])

  if test "$gcc_pthread_flag" = yes ; then
    thread_CFLAGS="-pthread"
    AC_SUBST(thread_CFLAGS)
  else
    AC_CHECK_LIB(pthread, pthread_create)
  fi
fi
if test "$target" = "BSD" -a `uname` != Darwin ; then
#  if test $freebsd_pthread = 4 ; then
    thread_CFLAGS="-pthread"
    AC_SUBST(thread_CFLAGS)
#  else
#    AC_CHECK_LIB(c_r, pthread_create, , 
#      AC_MSG_ERROR([You must have libc_r installed to build/run pdnsd!]))
#  fi;
fi

if test "$target" = "Linux" -a "$threadlib" = default; then
AC_MSG_CHECKING([if this is an NPTL-based system])
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $thread_CFLAGS"
AC_RUN_IFELSE([
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>

/* All this function does is return its PID (in a roundabout way). */
void *thread_func(void *data)
{
	*((int *)data)=getpid();
	return data;
}

int main()
{
	pthread_t thread;
	void *retval;
	int err,mainpid,thrdpid;

	err=pthread_create(&thread, NULL, thread_func, &thrdpid);
	if(err) {
		fprintf(stderr,"pthread_create failed: %s\n",strerror(err));
		return 1;
	}
	err=pthread_join(thread,&retval);
	if(err) {
		fprintf(stderr,"pthread_join failed: %s\n",strerror(err));
		return 1;
	}
	mainpid=getpid();
	/* In LinuxThreads implementations, the pids of the threads will usually differ
	   in a non Posix-compliant way. */
	fprintf(stderr,"main pid=%d, thread pid=%d\n",mainpid,*((int *)retval));
	return (*((int *)retval)!=mainpid);
}
],
[
  AC_MSG_RESULT([yes])
  threadlib=nptl
],
[
  AC_MSG_RESULT([no])
  threadlib=linuxthreads
],
[
  AC_MSG_RESULT([couldn't run test program])
  threadlib=linuxthreads
])
CFLAGS="$old_CFLAGS"
fi

if test "$threadlib" = nptl -o "$threadlib" = NPTL; then
	AC_DEFINE(THREADLIB_NPTL)
elif test "$threadlib" = linuxthreads2 -o "$threadlib" = LinuxThreads2 -o "$threadlib" = lt2; then
	AC_DEFINE(THREADLIB_LINUXTHREADS2)
fi

dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(fcntl.h malloc.h sys/ioctl.h sys/time.h syslog.h unistd.h)
AC_CHECK_HEADERS(sys/types.h sys/socket.h net/if.h netinet/in.h sys/poll.h,,,
[#include <stdio.h>
#if STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif
#if HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
])

dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_STRUCT_TM
AC_CHECK_TYPES(socklen_t,, AC_DEFINE(socklen_t,int),[#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>])
AC_CHECK_TYPES([struct in6_addr, struct in_pktinfo, struct ifreq],,,[#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>])

AC_MSG_CHECKING([for CPP C99 Variadic macro support])
AC_COMPILE_IFELSE([
#define a(...) junk(0,__VA_ARGS__)
extern void junk(int i,...);
int main()
{
  a(0);
  a("a");
  a(0, "a", 1);
  return 0;
}
],
  cpp_c99_variadic="yes", cpp_c99_variadic="no")
AC_MSG_RESULT([$cpp_c99_variadic])
if test $cpp_c99_variadic = yes; then
  AC_DEFINE(CPP_C99_VARIADIC_MACROS)
else
  if test "$GCC" != yes; then
    AC_MSG_ERROR([Compiler must support C99 or gcc variadic macros])
  fi;
fi

dnl Checks for library functions.
AC_FUNC_ALLOCA
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MEMCMP
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_SEARCH_LIBS(nanosleep, rt)
AC_SEARCH_LIBS(socket, socket,,,-lnsl)
AC_SEARCH_LIBS(inet_aton, resolv)
AC_CHECK_FUNCS(nanosleep gettimeofday mkfifo select socket strerror uname snprintf vsnprintf, true, 
		AC_MSG_ERROR([One of the functions required for pdnsd were not found.]))
AC_CHECK_FUNCS(poll, true, AC_DEFINE(NO_POLL))
AC_CHECK_FUNCS(strdup strndup stpcpy stpncpy strlcpy mempcpy getline asprintf vasprintf getpwnam_r inet_ntop inet_pton)

AC_OUTPUT([
pdnsd.spec
Makefile
file-list.base
contrib/Makefile
doc/Makefile
doc/pdnsd.8
doc/pdnsd.conf.5
doc/pdnsd.conf
src/Makefile
src/pdnsd-ctl/Makefile
src/rc/Makefile
src/rc/RedHat/Makefile
src/rc/RedHat/pdnsd
src/rc/SuSE/Makefile
src/rc/SuSE/pdnsd
src/rc/Debian/Makefile
src/rc/Debian/pdnsd
src/rc/Slackware/Makefile
src/rc/Slackware/rc.pdnsd
src/rc/ArchLinux/Makefile
src/rc/ArchLinux/pdnsd
src/test/Makefile
PKGBUILD
])
