dnl configure.in for cvs
AC_INIT(src/cvs.h)
dnl
AC_PREREQ(2.4)dnl Required Autoconf version.
dnl Do not use autoconf 2.12; it produces a configure script which produces
dnl a "internal 2K buffer" error on HPUX when run with /bin/sh.
dnl autoconf 2.10 seems like a good choice.
dnl
dnl It is possible that we should just change the above required version
dnl to 2.10; it seems like everyone is using 2.10 anyway, and there is
dnl at least some sentiment that we should be using a version which has
dnl --bindir (and correspondingly, using @bindir@ and friends in our
dnl Makefile.in files.  Rumor has it that autoconf 2.7
dnl introduced --bindir but the point is that 2.10 has it.
AC_CONFIG_HEADER(config.h src/options.h)
AC_CANONICAL_SYSTEM

AC_PROG_CC

AC_AIX
AC_MINIX
AC_ISC_POSIX
if test "$ISC" = yes; then
CFLAGS="$CFLAGS -D_SYSV3"
LIBS="-lcrypt $LIBS"
fi

AC_PREFIX_PROGRAM(cvs)

dnl FIXME: AC_C_CROSS is considered obsolete by autoconf 2.12, and is
dnl pretty ugly to start with.  But it isn't obvious to me how we should
dnl be handling the uses of cross_compiling below.
AC_C_CROSS

AC_C_CONST

AC_PROG_INSTALL
AC_CHECK_TOOL(RANLIB, ranlib, :)
AC_CHECK_TOOL(AR, ar, :)
AC_ARFLAGS
AC_PROG_YACC
AC_PROG_MAKE_SET

AC_PATH_PROG(perl_path, perl, no)
AC_PATH_PROG(csh_path, csh, no)

AC_SYS_INTERPRETER
if test X"$ac_cv_sys_interpreter" != X"yes" ; then
  # silly trick to avoid problems in AC macros...
  ac_msg='perl scripts using #! may not be invoked properly'
  AC_MSG_WARN($ac_msg)
fi

AC_HEADER_STDC
AC_CHECK_HEADERS(errno.h unistd.h string.h memory.h utime.h fcntl.h ndbm.h \
		 limits.h sys/file.h \
                 sys/param.h sys/select.h sys/time.h sys/timeb.h \
                 io.h direct.h sys/bsdtypes.h sys/resource.h)
AC_HEADER_SYS_WAIT
AC_HEADER_STAT
AC_HEADER_TIME
AC_HEADER_DIRENT
AC_TYPE_SIGNAL
AC_TYPE_UID_T
AC_TYPE_MODE_T
AC_TYPE_SIZE_T
AC_TYPE_PID_T
AC_STRUCT_ST_BLKSIZE
AC_REPLACE_FUNCS(getpass mkdir rename strstr dup2 strerror valloc waitpid memmove strtoul)
AC_CHECK_FUNCS(fchmod fsync ftime mktemp putenv vprintf ftruncate timezone getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam tzset readlink wait3)

# We use our own version of getopt (including our own header file) if the
# system one doesn't have getopt_long.  The problem we have is that we can't
# just arbitrarily use the one in libs.  Some systems, notably those that use
# the Microsoft style of shared library linkage, require special "cruft" in
# the declarations (__declspec(dllimport)) to properly import global variables
# set by the shared library functions.  Thus we not only have to use the version
# of getopt supplied by the system, but we must also ensure that we use the
# getopt.h supplied by the system.  On the other hand, if we use our replacement
# getopt, then we must ensure that we also use the corresponding replacement
# getopt.h.  Using the system getopt() with our getopt.h or vice versa, is a sure
# recipe for disaster if there is any mismatch.

private_getopt=
AC_CHECK_FUNC(getopt_long, :, private_getopt=yes)
AC_CHECK_HEADER(getopt.h, AC_DEFINE(HAVE_GETOPT_H), private_getopt=yes)
if test -n "$private_getopt"; then
  getopt_dist=lib/getopt.h.dist
  getopt_used=lib/getopt.h
  LIBOBJS="$LIBOBJS getopt.o getopt1.o"
fi
AC_LINK_FILES($getopt_dist,$getopt_used)

dnl
dnl The CVS coding standard (as specified in HACKING) is that if it exists
dnl in SunOS4 and ANSI, we use it.  CVS itself, of course, therefore doesn't
dnl need HAVE_* defines for such functions, but diff wants them.
dnl
AC_DEFINE(HAVE_STRCHR)
AC_DEFINE(HAVE_MEMCHR)

dnl
dnl AC_FUNC_VFORK is rather baroque.  It seems to be rather more picky
dnl than, say, the Single Unix Specification (version 2), which simplifies
dnl a lot of cases by saying that the child process can't set any variables
dnl (thus avoiding problems with register allocation) or call any functions
dnl (thus avoiding problems with whether file descriptors are shared).
dnl It would be nice if we could just write to the Single Unix Specification.
dnl I think the only way to do redirection this way is by doing it in the
dnl parent, and then undoing it afterwards (analogous to windows-NT/run.c).
dnl That would appear to have a race condition if the user hits ^C (or
dnl some other signal) at the wrong time, as main_cleanup will try to use
dnl stdout/stderr.  So maybe we are stuck with AC_FUNC_VFORK.
dnl
AC_FUNC_VFORK
AC_FUNC_CLOSEDIR_VOID

dnl
dnl Check for shadow password support.
dnl
dnl We used to try to determine whether shadow passwords were actually in
dnl use or not, but the code has been changed to work right reguardless,
dnl so we can go back to a simple check.
AC_CHECK_LIB(sec, getspnam)
AC_CHECK_FUNCS(getspnam)

dnl We always use CVS's regular expression matcher.
dnl This is because:
dnl (1) If memory serves, the syntax of the regular expressions
dnl handled by re_exec is not consistent from system to system, which
dnl is a Bad Thing because CVS passes this syntax out to the user.
dnl We might have better luck with the POSIX interface, if we really
dnl want to look for a system-supplied matcher.
dnl (2) It is necessary to make _sure_ that we get a regex.h and regex.c
dnl that match each other.  In particular, rx and the CVS/emacs
dnl regex.c have a different "struct re_pattern_buffer" and so using
dnl the system regex.h and our regex.c, or vice versa, will tend to
dnl cause a core dump.
dnl (3) Just as a random data point, CVS uses re_exec (a BSD interface);
dnl libdiff uses re_compile_pattern (a GNU interface, I think).  Diff
dnl should probably be fixed to have the caller (CVS) supply the regexp
dnl matching.
dnl
dnl AC_CHECK_FUNC(re_exec, :, LIBOBJS="$LIBOBJS regex.o")
AC_FUNC_UTIME_NULL
AC_SYS_LONG_FILE_NAMES

AC_MSG_CHECKING([for working fnmatch function])
AC_CACHE_VAL(ccvs_cv_sys_working_fnmatch,
[AC_TRY_RUN([
#include <fnmatch.h>
int
main ()
{
  exit ((fnmatch ("a", "a", FNM_PATHNAME) == 0
	 && fnmatch ("a", "b", FNM_PATHNAME) == FNM_NOMATCH)
	? 0 : 1);
}],
ccvs_cv_sys_working_fnmatch=yes,
ccvs_cv_sys_working_fnmatch=no,
ccvs_cv_sys_working_fnmatch=no)])
if test $ccvs_cv_sys_working_fnmatch = no; then
  LIBOBJS="$LIBOBJS fnmatch.o"
fi
AC_MSG_RESULT($ccvs_cv_sys_working_fnmatch)

# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
# libsocket.so which has a bad implementation of gethostbyname (it
# only looks in /etc/hosts), so we only look for -lsocket if we need
# it.
AC_CHECK_FUNC(connect, :, 
[case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl_s, printf) ;;
esac
case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl, printf) ;;
esac
case "$LIBS" in
*-lsocket*) ;;
*) AC_CHECK_LIB(socket, connect) ;;
esac
case "$LIBS" in
*-linet*) ;;
*) AC_CHECK_LIB(inet, connect) ;;
esac
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
dnl has been cached.
if test "$ac_cv_lib_socket_connect" = "yes" || test "$ac_cv_lib_inet_connect" = "yes"; then
  ac_cv_func_connect=yes
  AC_DEFINE(HAVE_CONNECT)
fi])

dnl
dnl set $(KRB4) from --with-krb4=value -- WITH_KRB4
dnl
dnl If you change this, keep in mind that some systems have a bogus
dnl libkrb in the system libraries, so --with-krb4=value needs to
dnl override the system -lkrb.
dnl
KRB4=/usr/kerberos
define(WITH_KRB4,[
AC_ARG_WITH([krb4],
  [  --with-krb4=value       set default \$(KRB4) from value],
  [KRB4=$withval],
)dnl
echo "default place for krb4 is $KRB4"
AC_SUBST(KRB4)])dnl
WITH_KRB4

krb_h=
AC_MSG_CHECKING([for krb.h])
if test "$cross_compiling" != yes && test -r $KRB4/include/krb.h; then
   hold_cflags=$CFLAGS
   CFLAGS="$CFLAGS -I$KRB4/include"
   AC_TRY_LINK([#include <krb.h>],[int i;],
          [krb_h=yes krb_incdir=$KRB4/include],
          [CFLAGS=$hold_cflags
           AC_TRY_LINK([#include <krb.h>],[int i;],
             [krb_h=yes krb_incdir=])])
   CFLAGS=$hold_cflags
else
   AC_TRY_LINK([#include <krb.h>],[int i;],
             [krb_h=yes krb_incdir=])
fi
if test -z "$krb_h"; then
  AC_TRY_LINK([#include <krb.h>],[int i;],
    [krb_h=yes krb_incdir=],
    [if test "$cross_compiling" != yes && test -r $KRB4/include/kerberosIV/krb.h; then
       hold_cflags=$CFLAGS
       CFLAGS="$CFLAGS -I$KRB4/include/kerberosIV"
       AC_TRY_LINK([#include <krb.h>],[int i;],
	 [krb_h=yes krb_incdir=$KRB4/include/kerberosIV])
       CFLAGS=$hold_cflags
     fi])
fi
AC_MSG_RESULT($krb_h)

includeopt=
AC_SUBST(includeopt)
if test -n "$krb_h"; then
  krb_lib=
  if test "$cross_compiling" != yes && test -r $KRB4/lib/libkrb.a; then
       hold_ldflags=$LDFLAGS
       LDFLAGS="-L${KRB4}/lib $LDFLAGS"
       AC_CHECK_LIB(krb,printf,[krb_lib=yes krb_libdir=${KRB4}/lib],
           [LDFLAGS=$hold_ldflags
            # Using open here instead of printf so we don't
            # get confused by the cached value for printf from above.
            AC_CHECK_LIB(krb,open,[krb_lib=yes krb_libdir=])])
       LDFLAGS=$hold_ldflags
  else
       AC_CHECK_LIB(krb,printf,[krb_lib=yes krb_libdir=])
  fi
  if test -n "$krb_lib"; then
    AC_DEFINE(HAVE_KERBEROS)
    test -n "${krb_libdir}" && LIBS="${LIBS} -L${krb_libdir}"
    LIBS="${LIBS} -lkrb"
    # Put -L${krb_libdir} in LDFLAGS temporarily so that it appears before
    # -ldes in the command line.  Don't do it permanently so that we honor
    # the user's setting for LDFLAGS
    hold_ldflags=$LDFLAGS
    test -n "${krb_libdir}" && LDFLAGS="$LDFLAGS -L${krb_libdir}"
    AC_CHECK_LIB(des,printf,[LIBS="${LIBS} -ldes"])
    LDFLAGS=$hold_ldflags
    if test -n "$krb_incdir"; then
      includeopt="${includeopt} -I$krb_incdir"
    fi
  fi
fi
AC_CHECK_FUNCS(krb_get_err_text)

dnl
dnl Use --with-gssapi=DIR to enable GSSAPI support.
dnl
GSSAPI=/usr/cygnus/kerbnet
define(WITH_GSSAPI,[
AC_ARG_WITH([gssapi],
  [  --with-gssapi=value     GSSAPI directory],
  [GSSAPI=$withval],
)dnl
echo "default place for GSSAPI is $GSSAPI"
AC_SUBST(GSSAPI)])dnl
WITH_GSSAPI

hold_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$GSSAPI/include "
AC_CHECK_HEADERS(krb5.h gssapi.h gssapi/gssapi.h gssapi/gssapi_generic.h)
CPPFLAGS=$hold_cppflags

if test "$ac_cv_header_krb5_h" = "yes" && 
   (test "$ac_cv_header_gssapi_h" = "yes" ||
    test "$ac_cv_header_gssapi_gssapi_h" = "yes"); then
  AC_DEFINE(HAVE_GSSAPI)
  includeopt="${includeopt} -I$GSSAPI/include"
  # FIXME: This is ugly, but these things don't seem to be standardized.
  if test "$ac_cv_header_gssapi_h" = "yes"; then
    LIBS="$LIBS -L$GSSAPI/lib -lgssapi -lkrb5 -lasn1 -ldes -lroken"
  else
    LIBS="$LIBS -L$GSSAPI/lib -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err"
  fi
  save_CPPFLAGS=$CPPFLAGS
  CPPFLAGS="-I$GSSAPI/include $CPPFLAGS"
  if test "$ac_cv_header_gssapi_h" = "yes"; then
    AC_EGREP_HEADER(GSS_C_NT_HOSTBASED_SERVICE, gssapi.h, AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE))
  else
    AC_EGREP_HEADER(GSS_C_NT_HOSTBASED_SERVICE, gssapi/gssapi.h, AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE))
  fi
  CPPFLAGS=$save_CPPFLAGS
  # This is necessary on Irix 5.3, in order to link against libkrb5 --
  # there, an_to_ln.o refers to things defined only in -lgen.
  AC_CHECK_LIB(gen, compile)
fi

dnl
dnl Use --with-encryption to turn on encryption support
dnl
AC_ARG_ENABLE(encryption,
  [  --enable-encryption     enable encryption support],
  [case "${enableval}" in
    yes) encryption=true ;;
    no) encryption=false ;;
    *) AC_MSG_ERROR(bad value ${enableval} for encryption option) ;;
   esac],
  [encryption=false])
if test "$encryption" = "true"; then
  AC_DEFINE(ENCRYPTION)
fi

AC_CHECK_FUNC(gethostname, :, LIBOBJS="$LIBOBJS hostname.o")

AC_FUNC_ALLOCA

# Check for options requesting client and server feature. If none are
# given and we have connect(), we want the full client & server arrangement.
AC_ARG_ENABLE(client,
[  --enable-client         include code for running as a remote client (default)
  --disable-client        don't include remote client code],
[if test "$enable_client" = yes; then
  AC_DEFINE(CLIENT_SUPPORT)
fi],
[if test "$ac_cv_func_connect" = yes; then
  AC_DEFINE(CLIENT_SUPPORT)
fi])
AC_ARG_ENABLE(server,
[  --enable-server         include code for running as a server (default)
  --disable-server        don't include server code],
[if test "$enable_server" = yes; then
  AC_DEFINE(SERVER_SUPPORT)
fi],
[if test "$ac_cv_func_connect" = yes; then
  AC_DEFINE(SERVER_SUPPORT)
  enable_server=yes
fi])

### The auth server needs to be able to check passwords against passwd
### file entries, so we only #define AUTH_SERVER_SUPPORT if we can
### find the crypt function. 
###
### We used to test for crypt in libc first, and only add -lcrypt if
### we couldn't find it, but that interacts badly with the cache
### variables, the 'unset' command isn't portable, and I'm not sure
### there's any harm in just testing for -lcrypt first.

if test "$enable_server" = yes; then
AC_CHECK_LIB(crypt, crypt)
AC_CHECK_FUNCS(crypt)

if test "$ac_cv_func_crypt" = yes; then
  AC_DEFINE(AUTH_SERVER_SUPPORT)
fi
fi # enable_server

if test "$enable_server" = yes; then
# Begin BeOS hack - we really should do something more general to find out
# if NO_SOCKET_TO_FD needs to be defined. -fnf
if test "`uname`" = "BeOS"; then
  AC_DEFINE(NO_SOCKET_TO_FD)
fi
# End BeOS hack
fi # enable_server

dnl For the moment we will assume that all systems which have
dnl the unixyness to run configure are unixy enough to do the
dnl PreservePermissions stuff.  I have this sinking feeling that
dnl things won't be that simple, before long.
AC_DEFINE(PRESERVE_PERMISSIONS_SUPPORT)

dnl On cygwin32, we configure like a Unix system, but we use the
dnl Windows support code in lib/fncase.c to handle the case
dnl insensitive file system.  We also need some support libraries.  We
dnl do this at the end so that the new libraries are added at the end
dnl of LIBS.
AC_CACHE_CHECK(for cygwin32, ccvs_cv_sys_cygwin32,
[AC_TRY_COMPILE([], [return __CYGWIN32__;],
ccvs_cv_sys_cygwin32=yes, ccvs_cv_sys_cygwin32=no)])
if test $ccvs_cv_sys_cygwin32 = yes; then
  LIBOBJS="$LIBOBJS fncase.o"
  LIBS="$LIBS -ladvapi32"

  dnl On Windows you can only change file times if you can write to
  dnl the file.  cygwin32 should really handle this for us, but as of
  dnl January 1998 it doesn't.
  AC_DEFINE(UTIME_EXPECTS_WRITABLE)

  dnl On Windows we must use setmode to change between binary and text
  dnl mode.
  AC_DEFINE(USE_SETMODE_STDOUT)
  AC_DEFINE(HAVE_SETMODE)
fi

test -f src/options.h && (
  AC_MSG_WARN(saving ./src/options.h in ./src/options.h-SAVED)
  AC_MSG_WARN(You may wish to check that local options have not been lost.)
  AC_MSG_WARN(Do not re-run ./configure or ./config.status until you have....)
  cp ./src/options.h ./src/options.h-SAVED
)

AC_OUTPUT(Makefile lib/Makefile src/Makefile zlib/Makefile diff/Makefile doc/Makefile \
	  man/Makefile tools/Makefile \
	  contrib/Makefile contrib/elib/Makefile\
	  windows-NT/Makefile windows-NT/SCC/Makefile \
	  os2/Makefile emx/Makefile vms/Makefile \
	  stamp-h)
