dnl
dnl   Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
dnl
dnl   This program is free software; you can redistribute it and/or modify
dnl   it under the terms of the GNU General Public License as published by
dnl   the Free Software Foundation; either version 2 of the License, or
dnl   (at your option) any later version.
dnl
dnl   This program is distributed in the hope that it will be useful,
dnl   but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
dnl   GNU General Public License for more details.
dnl
dnl   You should have received a copy of the GNU General Public License
dnl   along with this program; if not, write to the Free Software
dnl   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

AC_INIT(clamscan/clamscan.c)
AC_CREATE_TARGET_H(target.h)
AM_INIT_AUTOMAKE(clamav, "0.70-rc")
AM_CONFIG_HEADER(clamav-config.h)

LC_CURRENT=1
LC_REVISION=3
LC_AGE=0
LIBCLAMAV_VERSION="$LC_CURRENT":"$LC_REVISION":"$LC_AGE"
AC_SUBST(LIBCLAMAV_VERSION)

AC_PROG_AWK
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_LIBTOOL

dnl Version numbers for libtool

dnl LT_RELEASE=$CLAMAV_MAJOR_VERSION.$CLAMAV_MINOR_VERSION
dnl LT_CURRENT=$CLAMAV_MINOR_VERSION
dnl LT_REVISION=1
dnl LT_AGE=2

dnl AC_SUBST(LT_RELEASE)
dnl AC_SUBST(LT_CURRENT)
dnl AC_SUBST(LT_REVISION)
dnl AC_SUBST(LT_AGE)

dnl BUFFSIZE must be at least 16 kb !!!

AC_DEFINE(SCANBUFF, 131072, [scan buffer size])
AC_DEFINE(FILEBUFF, 8192,   [file i/o buffer size])

AC_HEADER_STDC
AC_CHECK_HEADERS(stdint.h unistd.h sys/int_types.h dlfcn.h inttypes.h sys/inttypes.h memory.h ndir.h stdlib.h strings.h string.h sys/mman.h sys/param.h sys/stat.h sys/types.h malloc.h poll.h)
AC_TYPE_OFF_T
AC_COMPILE_CHECK_SIZEOF(short)
AC_COMPILE_CHECK_SIZEOF(int)
AC_COMPILE_CHECK_SIZEOF(long)
AC_CHECK_FUNCS(poll setsid memcpy snprintf strerror_r)

have_pthreads=no
AC_CHECK_HEADER(pthread.h,[have_pthreads=yes],)

AC_CHECK_HEADER(zlib.h,[LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lz"; AC_DEFINE(HAVE_ZLIB_H,1,zlib installed)],[echo "Please install zlib and zlib-devel packages."; exit 1])

want_bzip2="yes"
AC_ARG_ENABLE(bzip2,
[  --disable-bzip2	  Disable bzip2 support.],
want_bzip2="no",)

if test "$want_bzip2" = "yes"
then
    AC_CHECK_HEADER(bzlib.h,[LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lbz2"; AC_DEFINE(HAVE_BZLIB_H,1,have bzip2)],)
    AC_CHECK_LIB(bz2, bzReadOpen, AC_DEFINE(NOBZ2PREFIX,1,bzip funtions do not have bz2 prefix),)
fi

want_clamuko="yes"
AC_ARG_ENABLE(clamuko,
[  --disable-clamuko	  Disable clamuko support (Linux and FreeBSD only)],
want_clamuko="no",)

AC_FUNC_SETPGRP

have_milter="no"
AC_CHECK_HEADER(libmilter/mfapi.h,have_milter="yes",)

AC_ARG_ENABLE(milter,
[  --enable-milter	  Build clamav-milter (if milter library found)],
,have_milter="no")

want_dsig="yes"
AC_ARG_ENABLE(dsig,
[  --disable-dsig	  Disable digital signature support.],
want_dsig="no",)

if test "$want_dsig" = "yes"
then
    AC_CHECK_LIB(gmp, __gmpz_init, [LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lgmp"; AC_DEFINE(HAVE_GMP,1,have gmp installed)], [AC_CHECK_LIB(gmp, mpz_init, [LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lgmp"; AC_DEFINE(HAVE_GMP,1,have gmp installed)], [echo "WARNING: GNU MP 2 or newer NOT FOUND - digital signature support will be disabled !"; want_dsig="no"])])
fi

AC_CHECK_HEADER(syslog.h,AC_DEFINE(CLAMD_USE_SYSLOG,1,[use syslog]),)

dnl AC_CHECK_LIB(c, strtok_r,, AC_DEFINE(NO_STRTOK_R))
dnl AC_CHECK_LIB(c, mkstemp, AC_DEFINE(HAVE_MKSTEMP),)

AC_ARG_ENABLE(pthreads,
[  --disable-pthreads      Disable POSIX threads support],
have_pthreads=no, )

AC_ARG_ENABLE(cr,
[  --disable-cr      Don't link with C reentrant library (BSD) ],
disable_cr=yes,)

test_urandom=yes
AC_ARG_ENABLE(urandom,
[  --disable-urandom       Disable test for /dev/urandom],
test_urandom=no,)

AC_ARG_ENABLE(id-check,
[  --enable-id-check	  Use id utility instead of /etc/passwd parsing],
use_id="yes", use_id="no")

AC_ARG_ENABLE(yp-check,
[  --enable-yp-check	  Use ypmatch utility instead of /etc/passwd parsing],
use_yp="yes", use_yp="no")

dnl clamav user
AC_ARG_WITH(user, 
[  --with-user=uid	  name of the clamav user (default=clamav).],
clamav_user="$withval", clamav_user="clamav")

dnl clamav group
AC_ARG_WITH(group, 
[  --with-group=gid	  name of the clamav group (default=clamav).],
clamav_group="$withval", clamav_group="clamav")

AC_DEFINE_UNQUOTED(CLAMAVUSER,"$clamav_user",[name of the clamav user])
AC_DEFINE_UNQUOTED(CLAMAVGROUP,"$clamav_group",[name of the clamav group])

test_clamav=yes
AC_ARG_ENABLE(clamav,
[  --disable-clamav	  Disable test for clamav user/group],
test_clamav=no,)

AC_ARG_ENABLE(debug,
[  --enable-debug	  Enable debug messages.],
AC_DEFINE(CL_DEBUG,1,[enable debugging]),)

AC_ARG_ENABLE(bigstack,
[  --enable-bigstack	  Increase thread stack size.],
AC_DEFINE(C_BIGSTACK,1,[Increase thread stack size.]),)

dnl database directory
AC_ARG_WITH(dbdir, 
[  --with-dbdir=path	  Path to virus database directory.],
db_dir="$withval", db_dir="_default_")

dnl main.cvd
AC_ARG_WITH(db1, 
[  --with-db1=name	  Name of the main database (main.cvd).],
AC_DEFINE_UNQUOTED(DB1NAME,"$withval",[Name of the main database]), AC_DEFINE(DB1NAME, "main.cvd",[Name of the main database]))

dnl daily.cvd
AC_ARG_WITH(db2, 
[  --with-db2=name	  Name of the daily database (daily.cvd).],
AC_DEFINE_UNQUOTED(DB2NAME,"$withval",[Name of the daily database]), AC_DEFINE(DB2NAME, "daily.cvd",[Name of the daily database]))

dnl I had problems with $pkgdatadir, that's why I'm using these funny checks
if test "$db_dir" = "_default_"
then
    if test "$prefix" = "NONE"
    then
	db_dir="$ac_default_prefix/share/clamav"
    else
	db_dir="$prefix/share/clamav"
    fi
fi

AC_DEFINE_UNQUOTED(DATADIR,"$db_dir", [Path to virus database directory.])
DBDIR="$db_dir"
AC_SUBST(DBDIR)

# config file
cfg_dir=`echo $sysconfdir | grep prefix`

if test -n "$cfg_dir"; then
    if test "$prefix" = "NONE"
    then
	cfg_dir="$ac_default_prefix/etc"
    else
	cfg_dir="$prefix/etc"
    fi
else
    cfg_dir="$sysconfdir"
fi

CFGDIR=$cfg_dir
AC_SUBST(CFGDIR)
AC_DEFINE_UNQUOTED(CONFDIR,"$cfg_dir",[where to look for the config file])

dnl Do not overwrite the current config file
AM_CONDITIONAL(INSTALL_CLAMAV_CONF, test ! -r "$cfg_dir/clamav.conf")
AM_CONDITIONAL(INSTALL_FRESHCLAM_CONF, test ! -r "$cfg_dir/freshclam.conf")

if test "$test_urandom" = "yes"
then
    if test -r /dev/urandom ; then
	AC_MSG_RESULT(/dev/(u)random detected.)
	AC_DEFINE(C_URANDOM,1,[use /dev/urandom])
    else
	AC_MSG_RESULT(/dev/(u)random not detected - using weak software rand())
    fi
fi

# tcpwrappers support
# rules from http://ma.ph-freiburg.de/tng/tng-technical/2002-01/msg00094.html
AC_ARG_WITH(tcpwrappers,
[  --with-tcpwrappers      Support hosts.allow / hosts.deny (default=auto)],
[ case "$withval" in
  yes|no) tcpw="$withval" ;;
  *)      AC_MSG_ERROR([--with-tcpwrappers does not take an argument]) ;;
  esac],
[ tcpw=auto ])

if test x"$tcpw" != xno; then
  err=no
  AC_CHECK_HEADER(tcpd.h,,err=yes)
  AC_CHECK_LIB(wrap,hosts_ctl,true,err=yes)
  if test x"$err" = xyes; then
    if test x"$tcpw" = xyes; then
      AC_MSG_ERROR([tcpwrappers not available])
    fi
  else
    AC_DEFINE(WITH_TCPWRAP,1,[tcpwrappers support])
    CLAMAV_MILTER_LIBS="-lwrap"
  fi
fi

# check for in_port_t definition
AC_TRY_RUN([
#include <sys/types.h>
#include <netinet/in.h>
int main(int argc, char **argv) { in_port_t pt; pt = 0; return pt; }
], AC_DEFINE(HAVE_IN_PORT_T,1,[in_port_t is defined]), AC_MSG_RESULT(in_port_t is not defined))

dnl CLAMSCAN_LIBS=""
dnl FRESHCLAM_LIBS=""
dnl CLAMD_LIBS=""
dnl TH_SAFE=""

case "$target_os" in
linux*)
    AC_DEFINE(C_LINUX,1,[target is linux])
    if test "$have_pthreads" = "yes"; then
	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lpthread"
	TH_SAFE="-thread-safe"
	AC_DEFINE(CL_THREAD_SAFE,1,[thread safe])
	AC_DEFINE(_REENTRANT,1,[thread safe])
	CLAMD_LIBS="-lpthread"
	CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lpthread"
	if test "$want_clamuko" = "yes"; then
	    AC_DEFINE(CLAMUKO,1,[enable clamuko])
	fi
	CLAMSCAN_LIBS="-lpthread"
    fi
    ;;
cygwin*)
    dnl It probably won't work.
    AC_DEFINE(C_CYGWIN,1,[os is cygwin])
    if test "$test_clamav" = "yes"; then
	if test ! -r /etc/passwd; then
	   test_clamav="no"
	fi
    fi
    if test "$have_pthreads" = "yes"; then
	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lpthread"
	TH_SAFE="-thread-safe"
	AC_DEFINE(CL_THREAD_SAFE,1,[thread safe])
	AC_DEFINE(_REENTRANT,1,[thread safe])
    fi
    ;;
solaris*)
    FRESHCLAM_LIBS="-lsocket -lnsl -lresolv"
    if test "$have_pthreads" = "yes"; then
	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lpthread"
	CLAMD_LIBS="-lpthread -lsocket -lnsl -lresolv"
	CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lpthread -lsocket -lnsl -lresolv"
	TH_SAFE="-thread-safe"
	AC_DEFINE(CL_THREAD_SAFE,1,[thread safe])
	AC_DEFINE(_REENTRANT,1,[thread safe])
    fi
    AC_DEFINE(C_SOLARIS,1,[os is solaris])
    ;;
freebsd*)
    if test "$have_pthreads" = "yes"; then
	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -pthread -lc_r"
	CLAMD_LIBS="-pthread -lc_r"
	CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -pthread -lc_r"
	TH_SAFE="-thread-safe"
	AC_DEFINE(CL_THREAD_SAFE,1,[thread safe])
	AC_DEFINE(_REENTRANT,1,[thread safe])
	if test "$want_clamuko" = "yes"; then
	    AC_DEFINE(CLAMUKO,1,[enable clamuko])
	fi
    fi
    AC_DEFINE(C_BSD,1,[os is freebsd])
    ;;
openbsd3.3*)
    if test "$have_pthreads" = "yes"; then
	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -pthread"
	if test "$disable_cr" = "yes"; then
	    CLAMD_LIBS="-pthread"
	CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -pthread"
	fi
	TH_SAFE="-thread-safe"
	AC_DEFINE(CL_THREAD_SAFE)
	AC_DEFINE(_REENTRANT)
    fi
    AC_DEFINE(C_BSD)
    ;;
openbsd*)
    if test "$have_pthreads" = "yes"; then
	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -pthread"
	if test "$disable_cr" = "yes"; then
	    CLAMD_LIBS="-pthread"
	    CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -pthread"
	else
	    CLAMD_LIBS="-pthread -lc_r"
	    CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -pthread -lc_r"
	fi
	TH_SAFE="-thread-safe"
	AC_DEFINE(CL_THREAD_SAFE,1,[thread safe])
	AC_DEFINE(_REENTRANT,1,[thread safe])
    fi
    AC_DEFINE(C_BSD,1,[os is bsd flavor])
    ;;
netbsd*)
    AC_MSG_RESULT(NetBSD detected. Disabling thread support.)
    have_pthreads="no"
    AC_DEFINE(C_BSD,1,[os is bsd flavor])
    ;;
bsd*)
    AC_MSG_RESULT(Unknown BSD detected. Disabling thread support.)
    have_pthreads="no"
    AC_DEFINE(C_BSD,1,[os is bsd flavor])
    ;;
beos*)
    AC_MSG_RESULT(BeOS detected. Disabling thread support.)
    have_pthreads="no"
    AC_DEFINE(C_BEOS,1,[os is beos])
    ;;
darwin*)
    AC_DEFINE(C_BSD,1,[os is bsd flavor])
    AC_DEFINE(C_DARWIN,1,[os is darwin])
    use_netinfo="yes"
    dnl have_pthreads="no"
    dnl AC_MSG_RESULT(Darwin detected. Disabling thread support.)
    ;;
sco*)
    dnl njh@bandsman.sco.uk: SCO Unix port
    FRESHCLAM_LIBS="-lsocket"
    CLAMD_LIBS="-lsocket"
    CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lsocket"
    dnl AC_DEFINE(NO_SNPRINTF)
    ;;
hpux*)
    if test "$have_pthreads" = "yes"; then
	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lpthread"
	CLAMD_LIBS="-lpthread"
	CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lpthread"
	TH_SAFE="-thread-safe"
	AC_DEFINE(CL_THREAD_SAFE,1,[thread safe])
	AC_DEFINE(_REENTRANT,1,[thread safe])
    fi
    AC_DEFINE(C_HPUX,1,[os is hpux])
    ;;
aix*)
    if test "$have_pthreads" = "yes"; then
	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lpthread"
	CLAMD_LIBS="-lpthread"
	CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lpthread"
	TH_SAFE="-thread-safe"
	AC_DEFINE(CL_THREAD_SAFE,1,[thread safe])
	AC_DEFINE(_REENTRANT,1,[thread safe])
    fi
    AC_DEFINE(C_AIX,1,[os is aix])
    ;;
irix*)
    if test "$have_pthreads" = "yes"; then
	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lpthread"
	CLAMD_LIBS="-lpthread"
	CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lpthread"
	TH_SAFE="-thread-safe"
	AC_DEFINE(CL_THREAD_SAFE,1,[thread safe])
	AC_DEFINE(_REENTRANT,1,[thread safe])
    fi
    AC_DEFINE(C_IRIX,1,[os is irix])
    dnl AC_DEFINE(NO_SNPRINTF,1,no snprintf available)
    ;;

*)
    ;;
esac

AC_SUBST(LIBCLAMAV_LIBS)
AC_SUBST(CLAMD_LIBS)
AC_SUBST(CLAMAV_MILTER_LIBS)
AC_SUBST(FRESHCLAM_LIBS)
AC_SUBST(TH_SAFE)

AM_CONDITIONAL(BUILD_CLAMD, test "$have_pthreads" = "yes")
AM_CONDITIONAL(HAVE_MILTER, test "$have_milter" = "yes")

if test "$have_pthreads" = "yes"
then
    AC_DEFINE(BUILD_CLAMD, 1, "build clamd")
fi

if test "$have_milter" = "yes"
then
    AC_PATH_PROG(SENDMAIL, sendmail, /usr/lib/sendmail, $PATH:/usr/lib:/usr/sbin:/etc:/usr/local/lib:/usr/local/sbin:/usr/bin:/usr/local/bin)
fi

dnl Check for clamav in /etc/passwd

if test "$test_clamav" = "yes"
then
    # parse /etc/passwd
    if test "$use_id" = no
    then
	AC_MSG_RESULT(Checking /etc/passwd...)
	if test -r /etc/passwd; then
	    clamavuser=`cat /etc/passwd|grep ${clamav_user}`
	    clamavgroup=`cat /etc/group|grep ${clamav_group}`
	fi
    else
	AC_MSG_RESULT(Checking id output...)
	id $clamav_user > /dev/null 2>&1
	if test "$?" = 0 ; then
	    clamavuser=1
	    AC_PATH_PROG(GETENT, getent)
	    if test -n "$GETENT" ; then
		clamavgroup=`$GETENT group | grep "^${clamav_group}:"`
	    else
		clamavgroup=`cat /etc/group|grep $clamav_group`
	    fi
	fi
    fi

    if test "$use_netinfo" = "yes"
    then
        clamavuser=`/usr/bin/nidump passwd . |grep ${clamav_user}`
        clamavgroup=`/usr/bin/nidump group . |grep ${clamav_group}`
    fi

    if test "$use_yp" = "yes"
    then
        clamavuser=`ypmatch ${clamav_user} passwd`
        clamavgroup=`ypmatch ${clamav_group} group`
    fi

    if test -z "$clamavuser" || test -z "$clamavgroup"
    then
        echo "ERROR: User \"$clamav_user\" (and/or group \"$clamav_group\") doesn't exist. Please create it. You can omit this check with the --disable-clamav option."
        exit 1
    else
        CLAMAVUSER="${clamav_user}"
        CLAMAVGROUP="${clamav_group}"
        AC_SUBST(CLAMAVUSER)
        AC_SUBST(CLAMAVGROUP)
    fi
fi

AC_C_CONST
AC_C_BIGENDIAN
if test $ac_cv_c_bigendian = yes; then
  AC_DEFINE(WORDS_BIGENDIAN,1,endianess)
else
  AC_DEFINE(WORDS_BIGENDIAN,0,endianess)
fi

dnl check for __attribute__((packed))
AC_MSG_CHECKING([for structure packing via __attribute__((packed))])
AC_CACHE_VAL(have_attrib_packed,[
	AC_TRY_COMPILE(,
		[struct { int i __attribute__((packed)); } s; ],
		[have_attrib_packed=yes],
		[have_attrib_packed=no])
	])
AC_MSG_RESULT($have_attrib_packed)

if test "$have_attrib_packed" = no; then
	AC_MSG_CHECKING(for structure packing via pragma)
	AC_CACHE_VAL(have_pragma_pack,[
		AC_TRY_RUN([int main(int argc, char **argv) {
#pragma pack(1)			/* has to be in column 1 ! */
			struct { char c; long l; } s;
			return sizeof(s)==sizeof(s.c)+sizeof(s.l) ? 0:1; } ],
			[have_pragma_pack=yes],
			[have_pragma_pack=no])
		])
	AC_MSG_RESULT($have_pragma_pack)
	AC_DEFINE(HAVE_PRAGMA_PACK, 1, "pragma pack")
fi

if test "$have_attrib_packed" = no -a "$have_pragma_pack" = no ; then
	AC_MSG_ERROR(Need to know how to pack structures with this compiler)
fi
if test "$have_attrib_packed" = yes; then
	AC_DEFINE(HAVE_ATTRIB_PACKED, 1, "attrib packed")
fi

# Check if <sys/select.h> needs to be included for fd_set
AC_MSG_CHECKING([for fd_set])
AC_TRY_COMPILE([#include <sys/types.h>],
        [fd_set readMask, writeMask;], have_fd_set=yes, have_fd_set=no)
if test $have_fd_set = yes; then
    AC_MSG_RESULT([yes, found in sys/types.h])
else
    AC_HEADER_EGREP(fd_mask, sys/select.h, have_fd_set=yes)
    if test $have_fd_set = yes; then
        AC_DEFINE(HAVE_SYS_SELECT_H, 1, "have <sys/select.h>")
        AC_MSG_RESULT([yes, found in sys/select.h])
    else
        AC_DEFINE(NO_FD_SET, 1, "no fd_set")
        AC_MSG_RESULT(no)
    fi
fi

AC_MSG_CHECKING(Default FD_SETSIZE value)
AC_TRY_RUN([
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/types.h>
main() {
        FILE *fp = fopen("conftestval", "w");
        fprintf (fp, "%d\n", FD_SETSIZE);
        exit(0);
}
],
DEFAULT_FD_SETSIZE=`cat conftestval`,
DEFAULT_FD_SETSIZE=256,
DEFAULT_FD_SETSIZE=256)
AC_MSG_RESULT($DEFAULT_FD_SETSIZE)
AC_DEFINE_UNQUOTED(DEFAULT_FD_SETSIZE, $DEFAULT_FD_SETSIZE, "default FD_SETSIZE value")

AC_OUTPUT([
libclamav/Makefile
clamscan/Makefile
database/Makefile
docs/Makefile
clamd/Makefile
clamdscan/Makefile
clamav-milter/Makefile
freshclam/Makefile
sigtool/Makefile
etc/Makefile
Makefile
])
