dnl Process this file with autoconf to produce a configure script.
AC_INIT([openCryptoki],[3.6.1],[opencryptoki-tech@lists.sourceforge.net])

dnl Needed for $target!
AC_CANONICAL_SYSTEM

AM_INIT_AUTOMAKE([foreign 1.6])

dnl Checks for header files.
AC_DISABLE_STATIC
LT_INIT

AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h limits.h strings.h sys/file.h syslog.h unistd.h])

dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_UID_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_STRUCT_TM
dnl Checks for library functions.
AC_FUNC_ALLOCA
AC_FUNC_MEMCMP
AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([getcwd])

dnl Used in various scripts
AC_PATH_PROG([ID], [id], [/us/bin/id])
AC_PATH_PROG([USERMOD], [usermod], [/usr/sbin/usermod])
AC_PATH_PROG([GROUPADD], [groupadd], [/usr/sbin/groupadd])
AC_PATH_PROG([CAT], [cat], [/bin/cat])
AC_PATH_PROG([CHMOD], [chmod], [/bin/chmod])
AC_PATH_PROG([CHGRP], [chgrp], [/bin/chgrp])
AC_PROG_SED
AC_PROG_MKDIR_P
AM_PROG_LEX
AC_PROG_YACC

dnl Define custom variables

lockdir=$localstatedir/lock/opencryptoki
AC_SUBST(lockdir)

logdir=$localstatedir/log/opencryptoki
AC_SUBST(logdir)

dnl ---
dnl --- Check all --enable/--disable-features
dnl ---

dnl --- Debugging support
AC_ARG_ENABLE([debug],
	AS_HELP_STRING([--enable-debug],[enable debugging build @<:@default=no@:>@]),
	[],
	[enable_debug=no])

dnl --- build testcases
AC_ARG_ENABLE([testcases],
	AS_HELP_STRING([--enable-testcases],[build the test cases @<:@default=no@:>@]),
	[],
	[enable_testcases=no])

dnl --- Check if building daemon
AC_ARG_ENABLE([daemon],
	AS_HELP_STRING([--enable-daemon],[build pkcsslotd daemon @<:@default=yes@:>@]),
	[],
	[enable_daemon=yes])

dnl --- Check if building library
AC_ARG_ENABLE([library],
	AS_HELP_STRING([--enable-library],[build opencryptoki libraries @<:@default=yes@:>@]),
	[],
	[enable_library=yes])

dnl --- Enable/disable tokens
dnl --- those have an additional 'check' state, which essentially means
dnl --- that it will enable it by default it dependencies are met

dnl --- ICA token
AC_ARG_ENABLE([icatok],
	AS_HELP_STRING([--enable-icatok],[build ica token @<:@default=enabled if libica is present@:>@]),
	[],
	[enable_icatok=check])

dnl --- CCA token
AC_ARG_ENABLE([ccatok],
	AS_HELP_STRING([--enable-ccatok],[build cca token (IBM Common Cryptographic Architecture) @<:@default=enabled in s390 arch@:>@]),
	[],
	[enable_ccatok=check])

dnl --- software token
AC_ARG_ENABLE([swtok],
	AS_HELP_STRING([--enable-swtok],[build software token @<:@default=enabled@:>@]),
	[],
	[enable_swtok=yes])

dnl --- EP11 token
AC_ARG_ENABLE([ep11tok],
        AS_HELP_STRING([--enable-ep11tok],[build ep11 token @<:@default=enabled@:>@]),
        [],
        [enable_ep11tok=check])

dnl --- TPM token
AC_ARG_ENABLE([tpmtok],
	AS_HELP_STRING([--enable-tpmtok],[build tpm token (Trusted Platform Module) @<:@default=enabled if TrouSerS is present@:>@]),
	[],
	[enable_tpmtok=check])

dnl -- icsf token (Integrated Cryptographic Service Facility remote token)
AC_ARG_ENABLE([icsftok],
	AS_HELP_STRING([--enable-iscftok],[build icsf token (Integrated Cryptographic Service Facility) @<:@default=enabled if OpenLDAP library is present@:>@]),
	[],
	[enable_icsftok=check])

dnl --- token-specific stuff
dnl --- pkcsep11_migrate
AC_ARG_ENABLE([pkcsep11_migrate],
	AS_HELP_STRING([--enable-pkcsep11_migrate],[build pkcsep11_migrate (EP11 token key migration tool) @<:@default=enabled if EP11 library is present@:>@]),
	[],
	[enable_pkcsep11_migrate=check])
dnl ---
dnl --- Check for external software
dnl --- Define what to check based on enabled features

dnl --- Openssl development files
AC_ARG_WITH([openssl],
	AS_HELP_STRING([--with-openssl@<:@=DIR@:>@],[OpenSSL development files location]),
	[],
	[with_openssl=check])

dnl --- Openldap development files
AC_ARG_WITH([openldap],
	AS_HELP_STRING([--with-openldap@<:@=DIR@:>@],[OpenLDAP development files location]),
	[],
	[with_openldap=check])

dnl --- Libica development files
AC_ARG_WITH([libica],
	AS_HELP_STRING([--with-libica@<:@=DIR@:>@],[libica development files location]),
	[],
	[with_libica=check])

dnl --- zcrypt development files
AC_ARG_WITH([zcrypt],
        AS_HELP_STRING([--with-zcrypt@<:@=DIR@:>@],[zcrypt development files location]),
        [],
        [with_zcrypt=check])

dnl --- TSS (TrouSerS) development files
AC_ARG_WITH([tss],
	AS_HELP_STRING([--with-tss@<:@=DIR@:>@],[TrouSerS development files location]),
	[],
	[with_tss=check])

dnl --- xcryptolinz development files (IBM CCA development files)
AC_ARG_WITH([xcryptolinz],
	AS_HELP_STRING([--with-xcryptolinz@<:@=DIR@:>@],[CCA library (xcryptolinz) location]),
	[],
	[with_xcryptolinz=check])

dnl --- systemd system unit files location
AC_ARG_WITH([systemd],
	AS_HELP_STRING([--with-systemd@<:@=DIR@:>@],[systemd system unit files location]),
	[],
	[with_systemd=no])

dnl ---
dnl ---
dnl --- Now that we have all the options, let's check for a valid build
dnl ---

case $target in
     *s390x*)
          ;;
     *s390*)
          CFLAGS="$CFLAGS -m31"
          ;;
     *ppc64* | *x86_64*)
	  ;;
     *ppc* | i*86*)
	  CFLAGS="$CFLAGS -m32"
	  ;;
esac

dnl --- enable_debug
if test "x$enable_debug" = "xyes"; then
	CFLAGS="$CFLAGS -gdwarf-2 -g3 -O0 -DDEBUG"
fi

dnl --- first, check what external software is present or specified
dnl --- with --with-package=DIR

dnl --- with_openssl
OPENSSL_CFLAGS=
OPENSSL_LIBS=
if test "x$with_openssl" != "xno"; then
	if test "x$with_openssl" != "xyes" -a "x$with_openssl" != "xcheck"; then
		OPENSSL_CFLAGS="-I$with_openssl"
		OPENSSL_LIBS="-L$with_openssl"
	fi
	old_cflags="$CFLAGS"
	old_libs="$LIBS"
	CFLAGS="$CFLAGS $OPENSSL_CFLAGS"
	LIBS="$LIBS $OPENSSL_LIBS"
	AC_CHECK_HEADER([openssl/ssl.h], [], [
		if test "x$with_openssl" != "xcheck"; then
			AC_MSG_ERROR([Build with OpenSSL requested but OpenSSL headers couldn't be found])
		fi
		with_openssl=no
	])
	if test "x$with_openssl" != "xno"; then
		AC_CHECK_LIB([crypto], [RSA_generate_key], [
			OPENSSL_LIBS="$OPENSSL_LIBS -lcrypto"
			with_openssl=yes
			], [
				if test "x$with_openssl" != "xcheck"; then
					AC_MSG_ERROR([Build with OpenSSL requested but OpenSSL libraries couldn't be found])
				fi
				with_openssl=no
		])
	fi
	if test "x$with_openssl" = "xno"; then
		CFLAGS="$old_cflags"
		LIBS="$old_libs"
	fi
fi
AC_SUBST([OPENSSL_CFLAGS])
AC_SUBST([OPENSSL_LIBS])

dnl --- with_openldap
OPENLDAP_CFLAGS=
OPENLDAP_LIBS=
if test "x$with_openldap" != "xno"; then
	if test "x$with_openldap" != "xyes" -a "x$with_openldap" != "xcheck"; then
		OPENLDAP_CFLAGS="-I$with_openldap"
		OPENLDAP_LIBS="-L$with_openldap"
	fi
	old_cflags="$CFLAGS"
	old_libs="$LIBS"
	CFLAGS="$CFLAGS $OPENLDAP_CFLAGS"
	LIBS="$LIBS $OPENLDAP_LIBS"
	AC_CHECK_HEADER([ldap.h], [], [
		if test "x$with_openldap" != "xcheck"; then
			AC_MSG_ERROR([Build with OpenLDAP requested but OpenLDAP headers couldn't be found])
		fi
		with_openldap=no
	])
	if test "x$with_openldap" != "xno"; then
		AC_CHECK_LIB([ldap], [ldap_extended_operation_s], [
			OPENLDAP_LIBS="$OPENLDAP_LIBS -lldap"
			with_openldap=yes
			], [
				if test "x$with_openldap" != "xcheck"; then
					AC_MSG_ERROR([Build with OpenLDAP requested but OpenLDAP libraries couldn't be found])
				fi
				with_openldap=no
		])
	fi
	if test "x$with_openldap" = "xno"; then
		CFLAGS="$old_cflags"
		LIBS="$old_libs"
	fi
fi
AC_SUBST([OPENLDAP_CFLAGS])
AC_SUBST([OPENLDAP_LIBS])

dnl --- with_libica
LIBICA_CFLAGS=
LIBICA_LIBS=
if test "x$with_libica" != "xno"; then
	if test "x$with_libica" != "xyes" -a "x$with_libica" != "xcheck"; then
		LIBICA_CFLAGS="-I$with_libica"
		LIBICA_LIBS="-L$with_libica"
	fi
	old_cflags="$CFLAGS"
	old_libs="$LIBS"
	CFLAGS="$CFLAGS $LIBICA_CFLAGS"
	LIBS="$LIBS $LIBICA_LIBS"
	AC_CHECK_HEADER([ica_api.h], [], [
		if test "x$with_libica" != "xcheck"; then
			AC_MSG_ERROR([Build with Libica requested but Libica headers couldn't be found])
		fi
		with_libica=no
	])
	if test "x$with_libica" != "xno"; then
		AC_CHECK_LIB([ica], [ica_open_adapter],
			[with_libica=yes], [
				if test "x$with_libica" != "xcheck"; then
					AC_MSG_ERROR([Build with Libica requested but Libica libraries (v 2.x or higher) couldn't be found])
				fi
				with_libica=no
		])
	fi
	if test "x$with_libica" = "xno"; then
		CFLAGS="$old_cflags"
		LIBS="$old_libs"
	fi
fi
AC_SUBST([LIBICA_CFLAGS])
AC_SUBST([LIBICA_LIBS])


dnl --- with_zcrypt
ZCRYPT_CFLAGS=
ZCRYPT_LIBS=
if test "x$with_zcrypt" != "xno"; then
	if test "x$with_zcrypt" != "xyes" -a "x$with_zcrypt" != "xcheck"; then
		ZCRYPT_CFLAGS="-I$with_zcrypt"
		ZCRYPT_LIBS="-L$with_zcrypt"
	fi
	old_cflags="$CFLAGS"
	old_libs="$LIBS"
	CFLAGS="$CFLAGS $ZCRYPT_CFLAGS"
	LIBS="$LIBS $ZCRYPT_LIBS"
	AC_CHECK_HEADER([asm/zcrypt.h], [], [
		if test "x$with_zcrypt" != "xcheck"; then
			AC_MSG_ERROR([Build with zcrypt requested but zcrypt headers couldn't be found])
		fi
		with_zcrypt=no
	])

	if test "x$with_zcrypt" != "xno"; then
		with_zcrypt=yes
	fi

	if test "x$with_zcrypt" = "xno"; then
		CFLAGS="$old_cflags"
		LIBS="$old_libs"
	fi

fi
AC_SUBST([ZCRYPT_CFLAGS])
AC_SUBST([ZCRYPT_LIBS])


dnl --- with_tss
TSS_CFLAGS=
TSS_LIBS=
if test "x$with_tss" != "xno"; then
	if test "x$with_tss" != "xyes" -a "x$with_tss" != "xcheck"; then
		TSS_CFLAGS="-I$with_tss"
		TSS_LIBS="-L$with_tss"
	fi
	old_cflags="$CFLAGS"
	old_libs="$LIBS"
	CFLAGS="$CFLAGS $TSS_CFLAGS"
	LIBS="$LIBS $TSS_LIBS"
	AC_CHECK_HEADER([tss/platform.h], [], [
		if test "x$with_tss" != "xcheck"; then
			AC_MSG_ERROR([Build with TSS requested but TSS headers couldn't be found])
		fi
		with_tss=no
	])
	if test "x$with_tss" != "xno"; then
		AC_CHECK_LIB([tspi], [Tspi_Context_Create],
			[with_tss=yes], [
				if test "x$with_tss" != "xcheck"; then
					AC_MSG_ERROR([Build with TSS requested but TSS libraries couldn't be found])
				fi
				with_tss=no
		])
	fi
	if test "x$with_tss" = "xno"; then
		CFLAGS="$old_cflags"
		LIBS="$old_libs"
	fi
fi
AC_SUBST([TSS_CFLAGS])
AC_SUBST([TSS_LIBS])

dnl --- with_xcryptolinz
XCRYPTOLINZ_CFLAGS=
XCRYPTOLINZ_LIBS=
if test "x$with_xcryptolinz" != "xno"; then
	if test "x$with_xcryptolinz" != "xyes" -a "x$with_xcryptolinz" != "xcheck"; then
		XCRYPTOLINZ_CFLAGS="-I$with_xcryptolinz"
		XCRYPTOLINZ_LIBS="-L$with_xcryptolinz"
	fi
	old_cflags="$CFLAGS"
	old_libs="$LIBS"
	CFLAGS="$CFLAGS $XCRYPTOLINZ_CFLAGS"
	LIBS="$LIBS $XCRYPTOLINZ_LIBS"
dnl - The above may not be necessary since opencryptoki brings this header file anyway.
	AC_CHECK_HEADER([csulincl.h], [], [
		if test "x$with_xcryptolinz" != "xcheck"; then
			AC_MSG_ERROR([Build with xcryptolinz requested but xcryptolinz headers couldn't be found])
		fi
		with_xcryptolinz=no
	])
	if test "x$with_xcryptolinz" != "xno"; then
		AC_CHECK_LIB([csulsapi], [CSNBKTC],
			[with_xcryptolinz=yes], [
				if test "x$with_xcryptolinz" != "xcheck"; then
					AC_MSG_ERROR([Build with xcryptolinz requested but xcryptolinz libraries couldn't be found])
				fi
				with_xcryptolinz=no
		])
	fi
	if test "x$with_xcryptolinz" = "xno"; then
		CFLAGS="$old_cflags"
		LIBS="$old_libs"
	fi
fi
AC_SUBST([XCRYPTOLINZ_CFLAGS])
AC_SUBST([XCRYPTOLINZ_LIBS])


dnl ---
dnl --- Now check enabled features, while making sure every required
dnl --- package is available
dnl ---

dnl --- enable_testcases
if test "x$enable_testcases" = "xyes"; then
	AC_CHECK_PROG([HAVE_EXPECT], [expect], [yes], [no])

	if test "x$HAVE_EXPECT" = "xno"; then
		AC_MSG_ERROR([*** testcases requires 'expect' interpreter, which wasn't found])
                enable_testcases=no
	fi
fi
AM_CONDITIONAL([ENABLE_TESTCASES], [test "x$enable_testcases" = "xyes"])

dnl --- enable_daemon
AM_CONDITIONAL([ENABLE_DAEMON], [test "x$enable_daemon" = "xyes"])

dnl --- enable_library
AM_CONDITIONAL([ENABLE_LIBRARY], [test "x$enable_library" = "xyes"])

dnl --- enable systemd and set unit dir
if test "x$with_systemd" != "xno"; then
	if test "x$with_systemd" != "xyes" -a "x$with_systemd" != "xcheck"; then
		unitdir=$with_systemd
		enable_systemd=yes
	else
		if test "x$with_systemd" = "xyes"; then
			unitdir=${ac_default_prefix}/lib/systemd/system
			enable_systemd=yes
		else
			enable_systemd=no
		fi
	fi
else
	enable_systemd=no
fi
AM_CONDITIONAL([ENABLE_SYSTEMD], [test "x$enable_systemd" = "xyes"])
AC_SUBST(unitdir)

dnl --- enable_icatok
if test "x$enable_icatok" = "xyes"; then
	if test "x$with_libica" != "xyes"; then
		AC_MSG_ERROR([ica token build requested but libica development files not found])
		enable_icatok=no
	fi
fi
if test "x$enable_icatok" = "xyes"; then
	if test "x$with_openssl" != "xyes"; then
		AC_MSG_ERROR([ica token build requested but OpenSSL development files not found])
		enable_icatok=no
	fi
fi
if test "x$enable_icatok" != "xno" -a "x$with_libica" != "xno" -a "x$with_openssl" != "xno"; then
	enable_icatok=yes
else
	enable_icatok=no
fi
AM_CONDITIONAL([ENABLE_ICATOK], [test "x$enable_icatok" = "xyes"])

dnl --- enable_ccatok
if test "x$enable_ccatok" != "xno"; then
	enable_ccatok=yes
else
	enable_ccatok=no
fi
AM_CONDITIONAL([ENABLE_CCATOK], [test "x$enable_ccatok" = "xyes"])

dnl --- enable_swtok
if test "x$enable_swtok" = "xyes"; then
	if test "x$with_openssl" != "xyes"; then
		AC_MSG_ERROR([software token build requested but OpenSSL development files not found])
		enable_swtok=no
	fi
fi
if test "x$enable_swtok" != "xno" -a "x$with_openssl" != "xno"; then
	enable_swtok=yes
else
	enable_swtok=no
fi
AM_CONDITIONAL([ENABLE_SWTOK], [test "x$enable_swtok" = "xyes"])

dnl --- enable_ep11tok
if test "x$enable_ep11tok" = "xyes"; then

	if test "x$with_zcrypt" != "xyes"; then
		AC_MSG_ERROR([ep11 token build requested but ep11 development files not found])
		enable_ep11=no
	fi
fi
if test "x$enable_ep11tok" != "xno" -a "x$with_zcrypt" != "xno"; then
        enable_ep11tok=yes
else
        enable_ep11tok=no
fi
AM_CONDITIONAL([ENABLE_EP11TOK], [test "x$enable_ep11tok" = "xyes"])

dnl --- enable_icsftok
if test "x$enable_icsftok" = "xyes"; then
	if test "x$with_openldap" != "xyes"; then
		AC_MSG_ERROR([ICSF token build requested but OpenLDAP development files not found])
		enable_icsftok=no
	fi
	if test "x$with_openssl" != "xyes"; then
		AC_MSG_ERROR([ICSF token build requested but OpenSSL development files not found])
		enable_icsftok=no
	fi
fi
if test "x$enable_icsftok" != "xno" -a "x$with_openldap" != "xno" -a "x$with_openssl" != "xno"; then
	enable_icsftok=yes
else
	enable_icsftok=no
fi
AM_CONDITIONAL([ENABLE_ICSFTOK], [test "x$enable_icsftok" = "xyes"])

dnl --- enable_tpmtok
if test "x$enable_tpmtok" = "xyes"; then
	if test "x$with_tss" != "xyes"; then
		AC_MSG_ERROR([tpm token build requested but TSS development files not found])
		enable_tpmtok=no
	fi
fi
if test "x$enable_tpmtok" != "xno" -a "x$with_tss" != "xno"; then
	enable_tpmtok=yes
else
	enable_tpmtok=no
fi
AM_CONDITIONAL([ENABLE_TPMTOK], [test "x$enable_tpmtok" = "xyes"])


dnl --- enable_pkcsep11_migrate
if test "x$enable_pkcsep11_migrate" = "xyes"; then
	if test "x$with_zcrypt" != "xyes"; then
		AC_MSG_ERROR([pkcsep11_migrate build requested but no ep11 libraries found])
		enable_pkcsep11_migrate=no
	fi
fi

if test "x$enable_pkcsep11_migrate" != "xno" -a "x$with_zcrypt" != "xno"; then
        enable_pkcsep11_migrate=yes
else
        enable_pkcsep11_migrate=no
fi

AM_CONDITIONAL([ENABLE_PKCSEP11_MIGRATE], [test "x$enable_pkcsep11_migrate" = "xyes"])

CFLAGS="$CFLAGS -DPKCS64 -D_XOPEN_SOURCE=600 -Wall -Wno-pointer-sign"

CFLAGS+=' -DCONFIG_PATH=\"$(localstatedir)/lib/opencryptoki\" -DSBIN_PATH=\"$(sbindir)\" -DLIB_PATH=\"$(libdir)\" -DLOCKDIR_PATH=\"$(lockdir)\" -DOCK_CONFDIR=\"$(sysconfdir)/opencryptoki\" -DOCK_LOGDIR=\"$(logdir)\"'

# At this point, CFLAGS is set to something sensible
AC_PROG_CC

AC_CONFIG_FILES([Makefile usr/Makefile \
          usr/include/Makefile \
          usr/include/pkcs11/Makefile \
          usr/lib/Makefile \
          usr/lib/pkcs11/Makefile \
          usr/lib/pkcs11/api/Makefile \
          usr/lib/pkcs11/api/shrd_mem.c \
          usr/lib/pkcs11/ica_s390_stdll/Makefile \
          usr/sbin/Makefile \
          usr/sbin/pkcsslotd/Makefile \
          usr/sbin/pkcsconf/Makefile \
          usr/sbin/pkcsicsf/Makefile \
          usr/sbin/pkcscca/Makefile \
          usr/sbin/pkcsep11_migrate/Makefile \
          usr/lib/pkcs11/soft_stdll/Makefile \
          usr/lib/pkcs11/ep11_stdll/Makefile \
          usr/lib/pkcs11/tpm_stdll/Makefile \
          usr/lib/pkcs11/cca_stdll/Makefile \
          usr/lib/pkcs11/icsf_stdll/Makefile \
          misc/Makefile \
	  testcases/Makefile \
	  testcases/common/Makefile \
	  testcases/crypto/Makefile \
	  testcases/pkcs11/Makefile \
	  testcases/login/Makefile \
	  testcases/misc_tests/Makefile \
	  man/Makefile \
	  man/man1/Makefile \
	  man/man1/pkcsconf.1 \
	  man/man1/pkcsicsf.1 \
	  man/man1/pkcscca.1 \
	  man/man1/pkcsep11_migrate.1 \
	  man/man5/Makefile \
	  man/man5/opencryptoki.conf.5 \
	  man/man7/Makefile \
	  man/man7/opencryptoki.7 \
	  man/man8/Makefile \
	  man/man8/pkcsslotd.8])
AC_OUTPUT

echo "Enabled features:"
echo "	Debug build:		$enable_debug"
echo "	Testcases:		$enable_testcases"
echo "	Daemon build:		$enable_daemon"
echo "	Library build:		$enable_library"
echo "	Systemd service:	$enable_systemd"
echo
echo "Enabled token types:"
echo "	ICA token:		$enable_icatok"
echo "	CCA token:		$enable_ccatok"
echo "	Software token:		$enable_swtok"
echo "	EP11 token:		$enable_ep11tok"
echo "	TPM token:		$enable_tpmtok"
echo "	ICSF token:		$enable_icsftok"
echo
echo "Token-specific features:"
echo "	pkcsep11migrate build:	$enable_pkcsep11_migrate"
echo
echo "CFLAGS=$CFLAGS"
echo
