#   Autoconf -*-shell-script-*- for CIPE
#
#   Copyright 1999 Olaf Titz <olaf@bigred.inka.de>
#
#   This program is free software; you can redistribute it and/or
#   modify it under the terms of the GNU General Public License
#   as published by the Free Software Foundation; either version
#   2 of the License, or (at your option) any later version.
#
AC_REVISION($Id: configure.in,v 1.33.2.4 2001/05/01 21:23:38 olaf Exp $)
dnl
dnl Process this file with autoconf to produce a configure script.
dnl
AC_PREREQ(2.13)
AC_INIT(cipe/ciped.c)
AC_CONFIG_HEADER($BUILD/config.h:conf/config.h.in pkcipe/config.h)
dnl $BUILD is set below - this works for autoconf 2.13, somewhat undocumented
AC_SUBST(VERSION)
VERSION=1.5.2
AC_SUBST(PVERSION)
PVERSION=2 dnl PKCIPE protocol
AC_SUBST(PVNOTE)
PVNOTE=0.1 dnl PKCIPE comment

AC_PROG_CC
test "$GCC" || AC_ERROR(You would not have much luck compiling kernel code with non-gcc...)

AC_PROG_CPP
AC_CHECK_PROGS(TEXINFO, texinfo tex, :)
AC_CHECK_PROGS(MAKEINFO, makeinfo, :)
AC_CHECK_PROGS(MAKE, gmake make, :)
$MAKE -v 2>&1 | grep -iqs 'GNU Make' || AC_ERROR(This compilation needs GNU make)

dnl  --- Find the Linux kernel, at least the headers ---

AC_MSG_CHECKING(for kernel include tree)
AC_SUBST(KSRC)
AC_ARG_WITH(linux,
[  --with-linux=DIR        Path to Linux source tree], KSRC=$withval)
AC_SUBST(KINC)
AC_ARG_WITH(linux-include,
[  --with-linux-include=DIR
                          Path to Linux include tree], KINC=$withval)
dnl use default only if nothing specified
if ! test "$KSRC$KINC" ; then
  KSRC=/usr/src/linux
fi
if test -z "$KINC" -o ! -d "$KINC" ; then
  if test -d "$KSRC" -a -f $KSRC/include/linux/autoconf.h ; then
    KINC=$KSRC/include
  fi
fi
if test -z "$KSRC" -o ! -d "$KSRC" ; then
  if test -f $KINC/include/linux/autoconf.h; then
    KINC=$KINC/include; dnl test for obvious mis-specification
  elif test -f $KINC/linux/autoconf.h; then
    KSRC=;
  fi
fi
if ! test -f $KINC/linux/version.h ; then
  AC_MSG_ERROR(no suitable configured kernel include tree found)
fi
dnl attempt to follow symlinks
if test -x /bin/pwd ; then
  test "$KSRC" && KSRC=`cd $KSRC; /bin/pwd`
  KINC=`cd $KINC; /bin/pwd`
fi
AC_MSG_RESULT($KINC)

AC_MSG_CHECKING(for kernel compile parameters)
if test -z "$KSRC" -o ! -f "$KSRC/Makefile" ; then
  AC_MSG_WARN(no Makefile - using default flags)
else
  cp $KSRC/Makefile conftest.make
  echo -e "conftest.CC:" >>conftest.make
  echo -e "\t@echo \$(CC)" >>conftest.make
  echo -e "conftest.CFLAGS:" >>conftest.make
  echo -e "\t@echo \$(CFLAGS) \$(MODFLAGS)" >>conftest.make
  here=`pwd`
  NKCC=`cd $KSRC; make -f $here/conftest.make conftest.CC`
  NKCFLAGS=`cd $KSRC; make -f $here/conftest.make conftest.CFLAGS`
  dnl some sanity checking
  echo "$NKCC $NKCFLAGS" | grep -qse '-I[[^ ]]*/include' || NKCC=""
  if test -z "$NKCC" ; then
    AC_MSG_WARN(not found - using default flags)
  else
    AC_MSG_RESULT($NKCC $NKCFLAGS)
  fi
  rm -f conftest.make
fi

dnl cancel -O arguments set by autoconf
if ! test "$ac_test_CFLAGS" = set; then
  CFLAGS=`echo $CFLAGS | sed 's,-O[[0-9]]*,,g'`
fi
CFLAGS="-Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce $CFLAGS"
dnl We separate compilation parameters in kernel and user part
AC_SUBST(KCPPFLAGS)     KCPPFLAGS="$CPPFLAGS"
AC_SUBST(KCFLAGS)       KCFLAGS="-pipe -O3 -funroll-loops $CFLAGS"
AC_SUBST(KDEFS)         KDEFS="-D__KERNEL__ -DMODULE $DEFS"
AC_SUBST(KLDFLAGS)      KLDFLAGS="-r -S"
dnl For user part. no-inline because egcs plays havoc with logs() in ciped
AC_SUBST(UCPPFLAGS)     UCPPFLAGS="$CPPFLAGS"
AC_SUBST(UCFLAGS)       UCFLAGS="-pipe -O3 -fno-inline-functions $CFLAGS"
AC_SUBST(UDEFS)         UDEFS="$DEFS"
AC_SUBST(ULDFLAGS)      ULDFLAGS="$LDFLAGS"
AC_SUBST(ULIBS)         ULIBS="$LIBS"

AC_MSG_CHECKING(for architecture)
ARCH=`uname -m | sed -e 's/i.86/i386/;s/sun4u/sparc64/;s/arm.*/arm/;s/sa110/arm/'`
AC_MSG_RESULT($ARCH)

dnl  --- Get Linux kernel version and compile parameters ---

oldcppflags="$CPPFLAGS"
CPPFLAGS="-I$KINC $CPPFLAGS"

AC_SUBST(KVERS)
AC_MSG_CHECKING(for kernel version)
AX_MACRO_STR(UTS_RELEASE, linux/version.h)
KVERS=$ax_result
AC_MSG_RESULT($KVERS)
case "$KVERS" in
2.[[01234]].*) ;;
*) AC_MSG_ERROR(Unsupported kernel version)
esac
kcomp=
if test -f $KINC/linux/compile.h; then
  AX_MACRO_STR(LINUX_COMPILER, linux/compile.h)
  kcomp=$ax_result
fi
if test -z "$kcomp" ; then
  AC_MSG_WARN(could not find kernel compiler version)
else
  tcomp=`${NKCC:-$CC} -v 2>&1 | tail -1`
  if ! test "$kcomp" = "$tcomp" ; then
    AC_MSG_WARN(Compiler version mismatch - try using $kcomp)
  fi
fi

AC_MSG_CHECKING(for SMP)
smp=0
case "$KVERS" in
2.[[01]].*)
  AX_EGREP([^ *SMP *= *1], $KSRC/Makefile, smp=1)
  ;;
*)
  AC_EGREP_CPP(yes, [
	#include <linux/autoconf.h>
	#ifdef CONFIG_SMP
	 yes
	#endif
  ], smp=1)
  ;;
esac
test "$smp" = 1 && AC_DEFINE(__SMP__)
AX_MSG_RESULT_YN($smp)

AC_SUBST(KCC)
CPPFLAGS="$oldcppflags"
dnl make sure the config includes come first
UCPPFLAGS="-I$KINC -I. -include ./config.h $UCPPFLAGS"

if test "$NKCC" ; then

KCC="$NKCC"
KCFLAGS="$NKCFLAGS"
KDEFS="-DKCC_BUILD"
KCPPFLAGS="-I. -include ./config.h $KCPPFLAGS"

else dnl NKCC not set

KCC="$CC"
KCPPFLAGS="-I$KINC -I. -include ./config.h $KCPPFLAGS"

dnl On the side of caution: the kernel headers contain inline funcs and
dnl we dont know for sure if they are alias-safe
AX_GCC_NOALIAS
test "$ax_cv_prog_gcc_noalias" = "yes" && KCFLAGS="$KCFLAGS -fno-strict-aliasing"

AC_MSG_CHECKING(for versioned symbols)
mv=0
AC_EGREP_CPP(yes, [
	#include <linux/autoconf.h>
	#ifdef CONFIG_MODVERSIONS
	 yes
	#endif
], mv=1)
AX_MSG_RESULT_YN($mv)
test "$mv" = 1 && AC_DEFINE(MODVERSIONS)

fi

dnl --- Configuration parameters ---

AC_SUBST(VERS)
AC_ARG_ENABLE(protocol,
[  --enable-protocol=n     Use protocol n (default 3, or 4)],
VERS=$enableval, VERS=3)
test "$VERS" -lt 3 && AC_MSG_WARN(Protocols less than 3 are deprecated)
verl=`expr substr abcdef $VERS 1`
AC_SUBST(CRYPTO)
AC_ARG_ENABLE(idea,
[  --enable-idea           Use the IDEA cipher (default is Blowfish)],
CRYPTO=IDEA;crypt=i, CRYPTO=Blowfish;crypt=b)
AC_SUBST(MODULE)
MODULE=cip$verl$crypt.o
AC_SUBST(CIPED)
CIPED=ciped-$verl$crypt
AC_ARG_ENABLE(debug,
[  --disable-debug         Disable debugging code in kernel module],
test "$enableval" = "no" && e=0, e=1)
test "$e" = "1" && AC_DEFINE(DEBUG)
AC_ARG_ENABLE(dyndev,
[  --disable-dyndev        Disable dynamic device allocation],
test "$enableval" = "no" && e=0, e=1)
test "$e" = "0" && AC_DEFINE(NO_DYNDEV)
AC_ARG_ENABLE(logfacility,
[  --enable-logfacility=x  Set syslog facility for ciped and pkcipe], [
  f=`echo "$enableval" | sed 's,^log_,,i' | tr a-z A-Z`
  AC_DEFINE_UNQUOTED(LOGFAC, LOG_$f)
], AC_DEFINE(LOGFAC, LOG_DAEMON))
AC_DEFINE_UNQUOTED(ProtocolVersion, $VERS)
AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
AC_ARG_ENABLE(bug-compatible,
[  --enable-bug-compatible Use old, broken interpretation of keys],
test "$enableval" = "no" || AC_DEFINE(BUG_COMPATIBLE))
AC_ARG_ENABLE(send-config,
[  --disable-send-config   Do not send configuration information],
test "$enableval" = "no" && e=0, e=1)
test "$e" = "0" && AC_DEFINE(DONT_SEND_CONF)

AC_ARG_ENABLE(keyfile,
[  --enable-keyfile=FILE   Location of default private key file],
AC_DEFINE_UNQUOTED(KEYFILE, "$enableval"))

AC_ARG_ENABLE(keydir,
[  --enable-keydir=FILE    Location (format string) of public key files],
AX_FMTSTRING(KEYDIR, "$enableval"))

AC_ARG_ENABLE(optdir,
[  --enable-optdir=FILE    Location (format string) of generated option files],
AX_FMTSTRING(OPTDIR, "$enableval"))

AC_ARG_WITH(ciped,
[  --with-ciped=FILE       Use specified ciped daemon for PKCIPE],
AC_DEFINE_UNQUOTED(CIPED, "$withval"))

dnl --- Determine assembler modules ---

AC_SUBST(ASMOBJS)
AC_SUBST(CCOBJS)
ASMOBJS=
CCOBJS=
AC_ARG_ENABLE(asm,
[  --disable-asm           Disable use of assembler code],
test "$enableval" = "no" && e=0, e=1)
AC_MSG_CHECKING(for assembler parts)
case "$CRYPTO" in
  Blowfish) AC_DEFINE(Crypto_Blowfish)
  if test $e -eq 1 -a -f cipe/bf-$ARCH.S; then
    AC_DEFINE(ASM_BF_Crypt)
    ASMOBJS=bf-$ARCH.o
  fi
  CCOBJS=bf.o
  ;;
  IDEA) AC_DEFINE(Crypto_IDEA)
  if test $e -eq 1 -a -f cipe/idea-$ARCH.S; then
    AC_DEFINE(ASM_Idea_Crypt)
    ASMOBJS=idea-$ARCH.o
  fi
  CCOBJS=idea0.o
  ;;
esac
if test "$ASMOBJS" ; then AC_MSG_RESULT($ASMOBJS) ; else AC_MSG_RESULT(none) ; fi
dnl sort out which CRC modules to use
AC_SUBST(CRCOBJS)
AC_SUBST(CRC32OBJS)
case "$VERS" in
1|2) CRCOBJS=crc.o ; CRC32OBJS=crc32.o ;;
*)   CRCOBJS=crc32.o ; CRC32OBJS= ;;
esac

AC_CHECK_FUNCS(mlock mlockall)

dnl  --- Find OpenSSL ---

BUILD_PKCIPE=1
SSLINCS=""
SSLLIBS=""
AC_ARG_WITH(ssl-includes,
[  --with-ssl-includes=DIR Location of OpenSSL includes],
SSLINCS=$withval)
AC_ARG_WITH(ssl-libs,
[  --with-ssl-libs=DIR     Location of OpenSSL libraries],
SSLLIBS=$withval)
AC_ARG_ENABLE(pkcipe,
[  --disable-pkcipe        Do not build PKCIPE],
test "$enableval" = "no" && BUILD_PKCIPE="")

if test "$BUILD_PKCIPE" ; then

AC_MSG_CHECKING(for OpenSSL)
H=openssl/ssl.h
for i in /usr/local /local /opt /usr ; do       dnl prefix
  for j in / /ssl /openssl /ssleay ; do         dnl package
    test -z "$SSLINCS" -a -f $i$j/include/$H && SSLINCS="$i$j/include"
    test -z "$SSLINCS" -a -f $i/include$j/$H && SSLINCS="$i/include$j"
    test -z "$SSLLIBS" -a -f $i$j/lib/libssl.so && SSLLIBS="$i$j/lib"
    test -z "$SSLLIBS" -a -f $i/lib$j/libssl.so && SSLLIBS="$i/lib$j"
    test -z "$SSLLIBS" -a -f $i$j/lib/libssl.a && SSLLIBS="$i$j/lib"
    test -z "$SSLLIBS" -a -f $i/lib$j/libssl.a && SSLLIBS="$i/lib$j"
  done
done
if test "$SSLINCS" -a "$SSLLIBS" ; then
  AC_MSG_RESULT([includes $SSLINCS, libs $SSLLIBS])
  CPPFLAGS="-I$SSLINCS $CPPFLAGS"
  LIBS="-L$SSLLIBS -lcrypto -ldl $LIBS"
else
  AC_MSG_RESULT(no)
  BUILD_PKCIPE=""
fi
SSLBIN=`dirname $SSLLIBS`/bin
AC_PATH_PROG(OPENSSL, openssl, no, "${SSLBIN}:${PATH}")
test "$OPENSSL" = "no" && AC_MSG_ERROR(openssl binary not found)
AC_MSG_CHECKING(OpenSSL version)
set `$OPENSSL version`
ov="$2"
AC_MSG_RESULT($ov)
case "$ov" in
0.9.[[6-9]]*) ;;
0.*) AC_MSG_WARN(Must have OpenSSL 0.9.6 or later)
     BUILD_PKCIPE="" ;;
*)   AC_MSG_WARN(Unknown OpenSSL version)
     BUILD_PKCIPE="" ;;
esac
test "$BUILD_PKCIPE" || AC_MSG_WARN(not building PKCIPE)

fi

dnl --- Check build dir name, do remaining defs ---

name=""
AC_ARG_ENABLE(name,
[  --enable-name=n         Set build directory name suffix],
name="-$enableval")

AC_SUBST(BUILD)
if test "$smp" = "1"; then
  BUILD=$KVERS-$ARCH-SMP-$verl$crypt$name
else
  BUILD=$KVERS-$ARCH-$verl$crypt$name
fi

AC_SUBST(BUILD_PKCIPE)
set `echo $VERSION | tr . ' '`
AC_DEFINE_UNQUOTED(VERSION_MAJ, $1)
AC_DEFINE_UNQUOTED(VERSION_MIN, $2)
AC_DEFINE_UNQUOTED(PVERSION, $PVERSION)
AC_DEFINE_UNQUOTED(PVNOTE, "$PVNOTE")

AC_OUTPUT(Makefile:conf/Makefile-top.in $BUILD/Makefile:conf/Makefile-obj.in
    lib/Makefile pkcipe/Makefile pkcipe/rsa-keygen,
    [chmod a+rx pkcipe/rsa-keygen])
