AC_INIT(mechanisms.h)
AC_PREREQ([2.54])

AC_CONFIG_AUX_DIR(config)
AC_CANONICAL_HOST

dnl Should we enable SASLAUTHd at all?
AC_ARG_WITH(saslauthd, [  --with-saslauthd=DIR    enable use of the saslauth daemon using state dir DIR ],
		with_saslauthd=$withval,
		with_saslauthd=yes)
  if test "$with_saslauthd" = yes; then
    with_saslauthd="/var/state/saslauthd"
  fi
  AC_DEFINE(HAVE_SASLAUTHD,[],[Include support for saslauthd?])
  AC_DEFINE_UNQUOTED(PATH_SASLAUTHD_RUNDIR, "$with_saslauthd",[Location of saslauthd socket])
AM_CONDITIONAL(SASLAUTHD, test "$with_saslauthd" != no)

AM_INIT_AUTOMAKE(saslauthd,2.1.21)
CMU_INIT_AUTOMAKE

dnl Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_AWK
AC_PROG_MAKE_SET
AC_PROG_LN_S
AC_PROG_INSTALL

dnl Checks for build foo
CMU_C___ATTRIBUTE__
CMU_GUESS_RUNPATH_SWITCH

dnl Checks for libraries.
CMU_SOCKETS

CMU_HAVE_OPENSSL
AC_MSG_CHECKING(for OpenSSL)
AC_MSG_RESULT($with_openssl)

SASL_DES_CHK

dnl mechanism-related checking
SASL_KERBEROS_V4_CHK
SASL_GSSAPI_CHK

if test "$gssapi" != no; then
	if test "$gss_impl" = "heimdal"; then
	    AC_DEFINE(KRB5_HEIMDAL,[],[Using Heimdal])
	fi
	AC_DEFINE(HAVE_GSSAPI,[],[Include GSSAPI/Kerberos 5 Support])
fi

SASL2_CRYPT_CHK

AC_ARG_ENABLE(sia, [  --enable-sia            enable SIA authentication [no] ],
  sia=$enableval,
  sia=no)
LIB_SIA=""
if test "$sia" != no; then
  if test -f /etc/sia/matrix.conf; then
    AC_DEFINE(HAVE_SIA,[],[Include SIA Support])
    LIB_SIA="-lsecurity -ldb -lm -laud"
  else
    AC_ERROR([No support for SIA found])
  fi
fi
AC_SUBST(LIB_SIA)

AC_ARG_ENABLE(auth-sasldb, [  --enable-auth-sasldb    enable experimental SASLdb authentication module [no] ],
  authsasldb=$enableval,
  authsasldb=no)
if test "$authsasldb" != no; then
  if test ! -d "../sasldb"; then
     echo "ERROR: Cannot build sasldb module outside of the full SASL source tree."
     exit 0;
  fi
  AC_DEFINE(AUTH_SASLDB,[],[Include SASLdb Support])
  SASL_DB_PATH_CHECK()
  SASL_DB_CHECK()
  SASL_DB_LIB="$SASL_DB_LIB ../sasldb/.libs/libsasldb.al"
fi

AC_ARG_WITH(pam, [  --with-pam=DIR          use PAM (rooted in DIR) [[yes]] ],
	with_pam=$withval,
	with_pam=yes)
if test "$with_pam" != no; then
  if test -d $with_pam; then
    CPPFLAGS="$CPPFLAGS -I${with_pam}/include"
    LDFLAGS="$LDFLAGS -L${with_pam}/lib"
  fi
  AC_CHECK_HEADERS(security/pam_appl.h pam/pam_appl.h)
  cmu_save_LIBS="$LIBS"
  AC_CHECK_FUNC(pam_start, :, 
	LIBS="-lpam $LIBS" 
	AC_TRY_LINK([[
#include <sys/types.h>
#ifdef HAVE_PAM_PAM_APPL_H
#include <pam/pam_appl.h>
#endif
#ifdef HAVE_SECURITY_PAM_H
#include <security/pam_appl.h>
#endif]],[[
const char *service="foo";
const char *user="bar";
pam_handle_t *pamh;
struct pam_conv *conv;
int baz;
baz = pam_start(service, user, conv, &pamh);
return 0;
]], LIBPAM="-lpam")
)
  LIBS="$cmu_save_LIBS $LIBPAM"
fi

AC_ARG_WITH(ipctype, [  --with-ipctype={unix,doors}    use ipctype [unix] ],
	with_ipctype=$withval,
	with_ipctype="unix")
MAIN_COMPAT_OBJ="saslauthd-${with_ipctype}.o"
AC_SUBST(MAIN_COMPAT_OBJ)
if test "$with_ipctype" = "doors"; then
  AC_DEFINE(USE_DOORS,[],[Use the doors IPC API])
  AC_DEFINE(SASLAUTHD_THREADED,[],[Saslauthd runs threaded?])
  LIBS="$LIBS -ldoor -lpthread"
fi

AC_MSG_CHECKING(for PAM support)
AC_MSG_RESULT($with_pam)
LIB_PAM=""
if test "$with_pam" != no; then
  AC_DEFINE(HAVE_PAM,[],[Support for PAM?])
  LIB_PAM="-lpam"
fi
AC_SUBST(LIB_PAM)

AC_CHECK_LIB(resolv, inet_aton)

AC_MSG_CHECKING(to include LDAP support)
AC_ARG_WITH(ldap, [  --with-ldap=DIR         use LDAP (in DIR) [no] ],
	with_ldap=$withval,
	with_ldap=no)
AC_MSG_RESULT($with_ldap)

if test -d $with_ldap; then
    CPPFLAGS="$CPPFLAGS -I${with_ldap}/include"
    CMU_ADD_LIBPATH(${with_ldap}/lib)
fi

LDAP_LIBS=""
if test "$with_ldap" != no; then
  AC_CHECK_LIB(ldap, ldap_initialize, [ AC_DEFINE(HAVE_LDAP,[],[Support for LDAP?])
                                        LDAP_LIBS="-lldap -llber"
					if test "$with_openssl" != "no"; then
					    LDAP_LIBS="$LDAP_LIBS -lcrypto $LIB_RSAREF"
					fi],,-llber)
  
fi
AC_SUBST(LDAP_LIBS)


dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_TIME
AC_CHECK_HEADERS(crypt.h fcntl.h krb5.h strings.h syslog.h unistd.h sys/time.h sys/uio.h)

dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST  
AC_TYPE_PID_T

LTLIBOBJS=`echo "$LIB@&t@OBJS" | sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'`
AC_SUBST(LTLIBOBJS)

dnl Checks for which function macros exist
AC_MSG_CHECKING(whether $CC implements __func__)
AC_CACHE_VAL(have_func,
[AC_TRY_LINK([#include <stdio.h>],[printf("%s", __func__);],
have_func=yes,
have_func=no)])
AC_MSG_RESULT($have_func)
if test "$have_func" = yes; then
       AC_DEFINE(HAVE_FUNC,[],[Does the compiler understand __func__])
else
       AC_MSG_CHECKING(whether $CC implements __PRETTY_FUNCTION__)
       AC_CACHE_VAL(have_pretty_function,
       [AC_TRY_LINK([#include <stdio.h>],[printf("%s", __PRETTY_FUNCTION__);],
       have_pretty_function=yes,
       have_pretty_function=no)])
       AC_MSG_RESULT($have_pretty_function)
       if test "$have_pretty_function" = yes; then
               AC_DEFINE(HAVE_PRETTY_FUNCTION,[],[Does compiler understand __PRETTY_FUNCTION__])
       else
               AC_MSG_CHECKING(whether $CC implements __FUNCTION__)
               AC_CACHE_VAL(have_function,
               [AC_TRY_LINK([#include <stdio.h>],[printf("%s", __FUNCTION__);],
               have_function=yes,
               have_function=no)])
               AC_MSG_RESULT($have_function)
               if test "$have_function" = yes; then
                       AC_DEFINE(HAVE_FUNCTION,[],[Does compiler understand __FUNCTION__])
               fi
       fi
fi

dnl Checks for library functions.
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(gethostname mkdir socket strdup)
AC_CHECK_FUNCS(getspnam getuserpw, break)
AC_CHECK_FUNCS(strlcat strlcpy)

dnl Check for getaddrinfo
GETADDRINFOOBJS=""
sasl_cv_getaddrinfo=no
IPv6_CHECK_FUNC(getaddrinfo,
		[AC_DEFINE(HAVE_GETADDRINFO,[],[Do we have a getaddrinfo() function?])], [sasl_cv_getaddrinfo=yes])
if test $sasl_cv_getaddrinfo = yes; then
	AC_LIBOBJ(getaddrinfo)
fi

dnl Check for getnameinfo
GETNAMEINFOOBJS=""
sasl_cv_getnameinfo=no
IPv6_CHECK_FUNC(getnameinfo,
		[AC_DEFINE(HAVE_GETNAMEINFO,[],[Do we have a getnameinfo() function?])], [sasl_cv_getnameinfo=yes])
if test $sasl_cv_getnameinfo = yes; then
	AC_LIBOBJ(getnameinfo)
fi

IPv6_CHECK_SS_FAMILY()
IPv6_CHECK_SA_LEN()
IPv6_CHECK_SOCKLEN_T()

AC_EGREP_HEADER(sockaddr_storage, sys/socket.h,
                AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE,[],[Do we have a sockaddr_storage struct?]))

AH_TOP([
#ifndef _SASLAUTHD_H
#define _SASLAUTHD_H

#include <stdio.h>
])

AH_BOTTOM([

#ifndef HAVE___ATTRIBUTE__
/* Can't use attributes... */
#define __attribute__(foo)
#endif

#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifndef WIN32
# include <netdb.h>   
# include <sys/param.h>
#else /* WIN32 */
# include <winsock2.h>
#endif /* WIN32 */ 
#include <string.h>

#include <netinet/in.h>

#ifndef HAVE_SOCKLEN_T
typedef unsigned int socklen_t;
#endif /* HAVE_SOCKLEN_T */

#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
#define _SS_MAXSIZE     128     /* Implementation specific max size */
#define _SS_PADSIZE     (_SS_MAXSIZE - sizeof (struct sockaddr))

struct sockaddr_storage {
        struct  sockaddr ss_sa;
        char            __ss_pad2[_SS_PADSIZE];
};
# define ss_family ss_sa.sa_family
#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */

#ifndef AF_INET6
/* Define it to something that should never appear */
#define AF_INET6        AF_MAX
#endif

/* Create a struct iovec if we need one */
#if !defined(HAVE_SYS_UIO_H)
struct iovec {
    long iov_len;
    char *iov_base;
};
#else
#include <sys/types.h>
#include <sys/uio.h>
#endif

#ifndef HAVE_GETADDRINFO
#define getaddrinfo     sasl_getaddrinfo
#define freeaddrinfo    sasl_freeaddrinfo
#define getnameinfo     sasl_getnameinfo
#define gai_strerror    sasl_gai_strerror
#include "gai.h"
#endif

#ifndef AI_NUMERICHOST   /* support glibc 2.0.x */
#define	AI_NUMERICHOST	4
#define NI_NUMERICHOST	2
#define NI_NAMEREQD	4
#define NI_NUMERICSERV	8
#endif

/* handy string manipulation functions */
#ifndef HAVE_STRLCPY
extern size_t saslauthd_strlcpy(char *dst, const char *src, size_t len);
#define strlcpy(x,y,z) saslauthd_strlcpy((x),(y),(z))
#endif
#ifndef HAVE_STRLCAT
extern size_t saslauthd_strlcat(char *dst, const char *src, size_t len);
#define strlcat(x,y,z) saslauthd_strlcat((x),(y),(z))
#endif

#endif
])

AC_CONFIG_HEADERS(saslauthd.h)

AC_OUTPUT(Makefile)
