dnl Process this file with Autoconf to produce a configure script.
dnl
dnl Please try to follow GNU conventions and Autoconf manual conventions as
dnl much as possible in this file so that any macros we develop can be easily
dnl contributed to the macro archive and possibly rolled into future versions
dnl of Autoconf so that we can stop supporting them.  This means, for example,
dnl that code excerpts should probably follow the GNU coding standards rather
dnl than INN's.
dnl
dnl If a check is any way non-trivial, please package it up in a macro with
dnl AC_DEFUN and put that macro into a separate file under m4.  Please also
dnl put any long code blocks into a separate macro rather than in-line in the
dnl test macro; this will make quoting issues much easier.  See the existing
dnl tests for details on how to do this.
dnl
dnl Try to do as much with AC_DEFINE and as little with AC_SUBST as is
dnl reasonable; obviously, makefile things like library paths and so forth and
dnl paths to programs have to use AC_SUBST, but any compile-time parameters
dnl are easier to handle with AC_DEFINE.  (And AC_SUBST is slower.)
dnl
dnl And remember: If you don't have any alternative available if your check
dnl for something fails, and there's no purpose served in aborting configure
dnl instead of the compile if what you're checking for is missing, don't
dnl bother checking for it.  Compile-time errors often produce a lot more
dnl useful information for someone debugging a problem than configure-time
dnl errors.
dnl
dnl Originally written by Forrest J. Cavalier III <mibsoft@epix.net> in 1998.
dnl Rewritten for Autoconf 2.57 by Russ Allbery in 2003.
dnl
dnl Various bug fixes, code and documentation improvements since its creation
dnl in 1998-2018, 2020-2026.

AC_INIT([INN], [2.8.0], [inn-workers@lists.isc.org],
    [inn], [https://www.isc.org/othersoftware/])
AC_PREREQ([2.64])
AC_CONFIG_AUX_DIR([support])

dnl Mention dependencies at the beginning of the configure output so that
dnl people do not waste too much time finding the right packages to install.
AC_MSG_NOTICE([Building INN requires the following dependencies to be met,
besides a working compiler, a POSIX-compliant shell and GNU make, as well as
Autoconf if you're bootstrapping the source code.
POSIX-compliant tools like tail, head or sed are required by some checks
during configure.  Please ensure they are present in the default PATH (for
instance on Solaris, /usr/xpg4/bin or /opt/csw/bin should be added to PATH).
---
*******************************************
** Debian and RedHat-based distributions **
*******************************************
The names of the deb and rpm packages are given to help you find them quicker.
---
Mandatory (deb / rpm):
- bison, flex / byacc, flex (for the innfeed build, if bootstrapping the source
  code)
- perl / perl (for various mandatory Perl scripts)
- default-mta / postfix (or any specific MTA, for moderated newsgroups)
---
Optional (deb / rpm):
- libdb-dev / libdb-devel (--with-bdb for ovdb overview)
- libcanlock-dev / libcanlock-devel (--with-canlock for Cancel-Lock support)
- libkrb5-dev / krb5-devel (--with-krb5 for a Kerberos v5 authenticator)
- libssl-dev / openssl-devel (--with-openssl for TLS support for readers)
- libperl-dev / perl-devel, perl-ExtUtils-Embed (--with-perl for Perl-based
  spam filtering and authentication)
- python3-dev, python3 / python3-devel, python3 (--with-python for Python-based
  spam filtering and authentication)
- libsasl2-dev / cyrus-sasl-devel (--with-sasl for SASL authentication support)
- libsqlite3-dev / sqlite-devel (--with-sqlite3 for ovsqlite overview)
- zlib1g-dev / zlib-devel (--with-zlib for compressed ovdb and ovsqlite,
  and the COMPRESS command for readers)
- libpam0g-dev / pam-devel (for PAM authentication support)
- libsystemd-dev, pkg-config / systemd-devel, pkg-config (for systemd
  notifications and socket activation)
---
Though not mandatory for the build, the following packages should be installed
if you plan on using the provided features (configure will properly sets their
paths in a few variables used by INN):
- gnupg / gnupg2 (for the verification of the signatures of control articles
  and NoCeM messages - GnuPG 1.x or 2.0.x preferred, as GnuPG 2.1.0 and above
  cannot verify signatures made with old PGP keys still used for some
  hierarchies)
- uucp / uucp (for the exchange of news articles with send-uucp)
- wget (for the synchronization of the active file against an external FTP or
  web server with actsyncd)
- various wide-spread programs like a modern awk implementation, grep, gzip
  (and eventually bzip2 and compress if you want to use other compression
  methods with send-uucp or rnews), sed and sort, probably already installed
  on your system, and used by INN in several scripts
---
Though not mandatory for the build, the following packages will also be useful:
- libgd-perl / perl-GD (for pictures in HTML daily Usenet reports)
- libencode-perl, libmime-tools-perl / perl-Encode, perl-MIME-tools (for the
  decoding of control articles by controlchan)
- libdbd-sqlite3-perl / perl-DBD-SQLite (for ovsqlite-util)
- cron and syslog, probably already installed on your system
---
*****************************************************************
** FreeBSD packages (and probably also other BSD-like systems) **
*****************************************************************
FreeBSD packages come with development headers by default and dependencies not
listed are satisfied by the base FreeBSD system.
---
Mandatory FreeBSD packages:
- gmake (INN needs to be built using gmake instead of make)
- autoconf (generate a configuration script)
- libtool (for library creation)
- perl5
---
Optional FreeBSD packages:
- db18 (--with-bdb --with-bdb-lib=/usr/local/lib/db18
        --with-bdb-include=/usr/local/include/db18, the "18" indicates version
        and can be replaced with another version, for ovdb overview)
- krb5 (--with-krb5)
- python3 (--with-python)
- cyrus-sasl (--with-sasl)
- sqlite3 (--with-sqlite3=/usr/local)
---
Optional packages provided by FreeBSD base and the ports tree:
- openssl (--with-openssl --with-openssl-lib=/usr/local
           --with-openssl-include=/usr/local if the version from ports
           is preferable to the one provided by the base system.)
---
Runtime optionals (see Linux equivalents above for descriptions):
- gnupg
- freebsd-uucp
- p5-GD
- p5-Encode, p5-MIME-Tools
- p5-DBD-SQLite
---
Unavailable packages (but may now be?):
- libcanlock (libcanlock is not yet available in the ports tree and needs
              manual compilation)
---
Happy building!])

dnl Ignore Automake conditionals (called in a few m4 macros) as INN does not
dnl uses Automake yet.
m4_define_default([AM_CONDITIONAL], [:])

dnl Lots of our macros are stored in separate files for ease of maintenance.
m4_include([m4/aux-libs.m4])
m4_include([m4/bdb.m4])
m4_include([m4/blocklist.m4])
m4_include([m4/canlock.m4])
m4_include([m4/cc-c-o.m4])
m4_include([m4/cc-flags.m4])
m4_include([m4/compress.m4])
m4_include([m4/inet-ntoa.m4])
m4_include([m4/iov-max.m4])
m4_include([m4/krb5-config.m4])
m4_include([m4/krb5.m4])
m4_include([m4/large-fpos.m4])
m4_include([m4/lib-depends.m4])
m4_include([m4/lib-helper.m4])
m4_include([m4/lib-pathname.m4])
m4_include([m4/libtool.m4])
m4_include([m4/lt~obsolete.m4])
m4_include([m4/ltoptions.m4])
m4_include([m4/ltsugar.m4])
m4_include([m4/ltversion.m4])
m4_include([m4/mmap.m4])
m4_include([m4/modes.m4])
m4_include([m4/openssl.m4])
m4_include([m4/pam-const.m4])
m4_include([m4/paths.m4])
m4_include([m4/perl.m4])
m4_include([m4/pkg.m4])
m4_include([m4/prog-ensure.m4])
m4_include([m4/python.m4])
m4_include([m4/sasl.m4])
m4_include([m4/sendfd.m4])
m4_include([m4/sendmail.m4])
m4_include([m4/snprintf.m4])
m4_include([m4/socket-unix.m4])
m4_include([m4/socket.m4])
m4_include([m4/sqlite3.m4])
m4_include([m4/syslog.m4])
m4_include([m4/systemd.m4])
m4_include([m4/users.m4])
m4_include([m4/vamacros.m4])
m4_include([m4/zlib.m4])

dnl By default, INN installs into its own independent tree.  Support for FHS
dnl is not yet implemented; once it is, this will need to become conditional
dnl on that support being disabled.
AC_PREFIX_DEFAULT([/usr/local/news])

dnl Make sure $prefix is set so that we can use it internally.
test x"$prefix" = xNONE && prefix="$ac_default_prefix"

dnl A few tests need to happen before any of the libtool tests.  We
dnl therefore lift them up to the top of the file.  (This is probably no
dnl longer needed now that we're running LT_INIT unconditionally, but
dnl we'll leave it alone until we switch to Automake.)
AC_PROG_CC
AC_USE_SYSTEM_EXTENSIONS
AC_SEARCH_LIBS([strerror], [cposix])
INN_PROG_CC_C_O
AC_CANONICAL_HOST

dnl Configure libtool and set the variables that we used to use when we
dnl supported builds without libtool.
LT_INIT
EXTLIB='la'
EXTOBJ='lo'
LIBTOOL='$(top)/libtool'
LIBTOOLCC='$(top)/libtool --mode=compile'
LIBTOOLINST='$(top)/libtool --mode=install'
LIBTOOLLD='$(top)/libtool --mode=link'
LIBTOOLLDDEPS='$(top)/libtool --mode=link --preserve-dup-deps'
CCOUTPUT='-c -o $@ $<'
AC_SUBST(EXTLIB)
AC_SUBST(EXTOBJ)
AC_SUBST(LIBTOOLCC)
AC_SUBST(LIBTOOLINST)
AC_SUBST(LIBTOOLLD)
AC_SUBST(LIBTOOLLDDEPS)
AC_SUBST(CCOUTPUT)

dnl If PIC objects are not wanted (--with-pic=no), an error occurs during
dnl the build of shared libraries.  Unfortunately, $pic_mode is set after
dnl calling LT_INIT whereas AC_DISABLE_SHARED must be given before, so we
dnl cannot automatically disable it.  Just bail out with an error.
AS_IF([test x"$pic_mode" = xno && test x"$enable_shared" = xyes],
    [AC_MSG_ERROR([Incompatible use of --without-pic and --enable-shared])])

dnl Command-line options.  Many of these macros just do the command-line
dnl component of a set of macros that have additional parts called later.
INN_ARG_PATHS
INN_ARG_SYSLOG
INN_ARG_USERS
INN_ARG_MODES
INN_ARG_COMPRESS
INN_ARG_SENDMAIL

dnl innbind by default only allows ports 119, 433 and 563 below 1024; if the user
dnl wants to use some other port as well, they must use this option.
AC_ARG_WITH([innd-port],
    [AS_HELP_STRING([--with-innd-port=PORT],
        [Additional low-numbered port for innbind])],
    [AC_DEFINE_UNQUOTED([INND_PORT], [$with_innd_port],
        [Additional permitted low-numbered port for innbind.])])

dnl Whether to use a different (less tested) history algorithm.  This will
dnl eventually be a runtime option rather than a compile-time option as soon
dnl as the #ifdefs can be untangled and put into the history API.  The output
dnl variable is needed for now to support news.daily.
DO_DBZ_TAGGED_HASH=DONT
inn_enable_tagged_hash=no
AC_ARG_ENABLE([tagged-hash],
    [AS_HELP_STRING([--enable-tagged-hash],
        [Use tagged hash table for history])],
    [if test "x$enableval" = xyes ; then
        DO_DBZ_TAGGED_HASH=DO
        inn_enable_tagged_hash=yes
        AC_DEFINE([DO_TAGGED_HASH], [1],
            [Define to use tagged hash for the history file.])
    fi])
AC_SUBST([DO_DBZ_TAGGED_HASH])

dnl Whether to enable the keyword generation code in innd.  Use of this code
dnl requires a regular expression library, which is checked for later on.
inn_enable_keywords=0
AC_ARG_ENABLE([keywords],
    [AS_HELP_STRING([--enable-keywords],
        [Automatic innd keyword generation support])],
    if test x"$enableval" = xyes ; then
        inn_enable_keywords=1
    fi)
AC_DEFINE_UNQUOTED([DO_KEYWORDS], [$inn_enable_keywords],
    [Define to 1 to compile in support for keyword generation code.])

dnl Whether to use the OS flags to enable large file support.  Ideally this
dnl should just always be turned on if possible and the various parts of INN
dnl that read off_t's from disk should adjust somehow to the size, but INN
dnl isn't there yet.  Currently tagged hash doesn't work with large file
dnl support due to assumptions about the size of off_t.
inn_enable_largefiles=no
AC_ARG_ENABLE([largefiles],
    [AS_HELP_STRING([--enable-largefiles],
        [Support for files larger than 2GB @<:@default=no@:>@])],
    if test x"$enableval" = xyes ; then
        inn_enable_largefiles=yes
    fi)
if test x"$inn_enable_tagged_hash" = xyes \
   && test x"$inn_enable_largefiles" = xyes ; then
    AC_MSG_ERROR([--enable-tagged-hash conflicts with --enable-largefiles.])
fi

dnl Checks for a recent enough Perl interpreter.
dnl Embedded Perl requires 5.004.  Use of the three-arg open and the our
dnl keyword requires 5.006, so makes 5.006 the minimum level; anyone should
dnl really have at least that these days.
dnl The recommendation in INSTALL and README is even a bit higher (Perl 5.8.0).
dnl An optional Perl module (INN::ovsqlite_client) actually requires Perl 5.8.0
dnl though.  Generating all the documentation from POD requires Perl 5.12.0
dnl but most of it can be generated with Perl 5.6.0.  If need be, the
dnl documentation can be fetched from the release tarball.
dnl We also check for useful Perl modules.
INN_PROG_PERL([5.006])
INN_PERL_CHECK_MODULE([Encode], [],
    [inn_perl_mod_warn="$inn_perl_mod_warn Encode (for controlchan)"])
INN_PERL_CHECK_MODULE([GD], [],
    [inn_perl_mod_warn="$inn_perl_mod_warn GD (for innreport's HTML output)"])
INN_PERL_CHECK_MODULE([MIME::Parser], [],
    [inn_perl_mod_warn="$inn_perl_mod_warn MIME::Parser (for controlchan)"])

dnl Support for embedded Perl.
AC_ARG_WITH([perl],
    [AS_HELP_STRING([--with-perl], [Embedded Perl script support @<:@no@:>@])],
    [AS_CASE([$withval],
        [yes],
            [DO_PERL=DO
             AC_DEFINE([DO_PERL], [1],
                 [Define to compile in Perl script support.])],
        [no],
            [DO_PERL=DONT],
        [AC_MSG_ERROR([invalid argument to --with-perl])])],
    [DO_PERL=DONT])

dnl If we aren't compiling with large-file support, strip out the large file
dnl flags from inn_perl_core_flags; otherwise, innd/cc.c and lib/qio.c
dnl disagree over the size of an off_t.  Since none of our calls into Perl
dnl use variables of type off_t, this should be harmless; in any event, it's
dnl going to be better than the innd/cc.c breakage.
AS_IF([test x"$DO_PERL" = xDO],
    [INN_LIB_PERL
     inn_perl_core_flags=" $PERL_CPPFLAGS "
     AS_IF([test x"$inn_enable_largefiles" != xyes],
        [for f in -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES ; do
            inn_perl_core_flags=`AS_ECHO(["$inn_perl_core_flags"]) | sed "s/ $f / /"`
         done])
     inn_perl_core_flags=`AS_ECHO(["$inn_perl_core_flags"]) | sed 's/^  *//'`
     inn_perl_core_flags=`AS_ECHO(["$inn_perl_core_flags"]) | sed 's/  *$//'`
     PERL_CPPFLAGS="$inn_perl_core_flags"],
    [PERL_CPPFLAGS=''
     PERL_LIBS=''
     AC_SUBST([PERL_CPPFLAGS])
     AC_SUBST([PERL_LIBS])])

dnl Support for embedded Python.
AC_ARG_WITH([python],
    [AS_HELP_STRING([--with-python],
                    [Embedded Python module support @<:@no@:>@])],
    [AS_CASE([$withval],
        [yes],
            [DO_PYTHON=DO
             AC_DEFINE([DO_PYTHON], [1],
                 [Define to compile in Python module support.])],
        [no],
            [DO_PYTHON=DONT],
        [AC_MSG_ERROR([invalid argument to --with-python])])],
    [DO_PYTHON=DONT])

dnl Checks for a recent enough Python interpreter for embedded Python.
dnl Requires 2.3.0 because configure looks for a shared Python library,
dnl installed in the main library location in Python 2.3.0 and later.
dnl Python 3.3.0 and later is also supported.
AS_IF([test x"$DO_PYTHON" = xDO],
    [INN_PROG_PYTHON([2.3.0], [3.3.0])
     INN_LIB_PYTHON])

dnl Set some configuration file defaults from the machine hostname.
HOSTNAME=`hostname 2> /dev/null || uname -n`
AC_SUBST(HOSTNAME)

dnl Checks whether pod2text supports the --guesswork option (available in
dnl podlators 5.01 and above).  If that's the case, pod2man also supports it
dnl (available since podlators 5.00).  This options permits disabling
dnl heuristics only intended for Perl documentation, because they prevent
dnl some patterns like C<@@NCM> (in perl-nocem man page) from being converted
dnl as expected.
AC_MSG_CHECKING([if pod2text supports --guesswork])
AS_IF([`AS_ECHO(["=head1 test"]) | pod2text --guesswork=none > /dev/null 2>&1`],
    [POD2TEXT_OPTION="--guesswork=none"
     AC_MSG_RESULT([yes])],
    [AC_MSG_RESULT([no])])
AC_SUBST(POD2TEXT_OPTION)

dnl Checks for programs.
AC_PROG_LEX([noyywrap])
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_MKDIR_P
AC_PROG_RANLIB
AC_PROG_YACC

dnl On Mac OS X Server, -traditional-cpp is needed for gcc for compiling as
dnl well as preprocessing according to Miro Jurisic <meeroh@meeroh.org>.
case "$CPP" in
*-traditional-cpp*)
    CFLAGS="-traditional-cpp ${CFLAGS}"
    CC_WARNINGS="-traditional-cpp ${CC_WARNINGS}"
    ;;
esac

case "$host" in

dnl When building on Linux, we need to compile with _GNU_SOURCE to get the
dnl right definitions of pread and pwrite and to get some other functions
dnl (like asprintf) that we use.
*linux*)
    AC_DEFINE([_GNU_SOURCE], [1],
        [Define if compiling on Linux to get prototypes for some functions.])
    ;;

dnl Detect BSD/OS for later use in nnrpd code.
*-bsdi*)
    AC_DEFINE([INN_BSDI_HOST], [1],
        [Define if compiling on BSD/OS systems.])
    ;;

dnl HP-UX's native compiler needs a special flag to turn on ANSI, and needs
dnl -g on link as well as compile for debugging to work.
*hpux*)
    if test x"$GCC" != xyes ; then
        CFLAGS="${CFLAGS} -Ae"
        CC_WARNINGS="${CC_WARNINGS} -Ae"
        case "$CFLAGS" in
        *-g*) LDFLAGS="$LDFLAGS -g" ;;
        esac
    fi
    ;;

dnl Mac OS X needed "-multiply_defined suppress" before this linker flag became
dnl obsolete (darwin13 is Mavericks, OS X 10.9).
*-darwin[[0-9]].*|*-darwin1[[0-2]].*)
    LDFLAGS="$LDFLAGS -multiply_defined suppress"
    ;;
esac

dnl Whether to add hardening flags to the build.  Ideally, this should just
dnl always be turned on wherever possible, but depending on the compiler and
dnl the platform, it might be useful to easily remove them at configure time.
inn_enable_hardening_flags=yes
AC_ARG_ENABLE([hardening-flags],
    [AS_HELP_STRING([--enable-hardening-flags],
        [Add hardening build flags like -fPIE @<:@default=yes@:>@])],
    [AS_IF([test x"$enableval" != xyes],
        [inn_enable_hardening_flags=no])])

dnl Checks for pathnames.  If AC_PROG_* does not manage to find a working
dnl program, INN_PATH_PROG_ENSURE will output an error.
AC_ARG_VAR([AWK], [Location of awk])
AC_ARG_VAR([EGREP], [Location of egrep])
AC_ARG_VAR([SED], [Location of sed])
AC_ARG_VAR([SORT], [Location of sort])
AC_ARG_VAR([SSLBIN], [Location of openssl])
AC_ARG_VAR([UUSTAT], [Location of uustat])
AC_ARG_VAR([UUX], [Location of uux])
AC_PROG_AWK
AC_PROG_EGREP
AC_PROG_SED
INN_PATH_PROG_ENSURE([AWK], [awk])
INN_PATH_PROG_ENSURE([EGREP], [egrep])
INN_PATH_PROG_ENSURE([SED], [sed])
INN_PATH_PROG_ENSURE([SORT], [sort])
AC_PATH_PROGS([SSLBIN], [openssl], [openssl])
AC_PATH_PROGS([UUSTAT], [uustat])
AC_PATH_PROGS([UUX], [uux], [uux])
INN_PATH_COMPRESS
INN_PATH_SENDMAIL

dnl Look for PGP 5.0's pgpv, then pgp, then pgpgpg (not sure why anyone would
dnl have pgpgpg and not gpgv, but it doesn't hurt).  Separately look for
dnl GnuPG (which we prefer) and whether it supports a flag introduced in
dnl GnuPG 2.0.23 to allow weak hash algorithms like MD5 in old PGP keys still
dnl used to sign control articles.
DO_PGPVERIFY=true
AC_ARG_VAR([GPGV], [Location of GnuPG gpgv program])
AC_ARG_VAR([GPG], [Location of GnuPG gpg program])
AC_ARG_VAR([PGP], [Location of PGP verification program])
AC_PATH_PROGS([GPGV], [gpgv1 gpgv gpgv2])
AC_PATH_PROGS([GPG], [gpg1 gpg gpg2])
AC_PATH_PROGS([PGP], [pgpv pgp pgpgpg])
if test -z "$PGP" && test -z "$GPGV" && test -z "$GPG" ; then
    DO_PGPVERIFY=false
fi
AC_SUBST([DO_PGPVERIFY])

GPG_HAS_ALLOW_WEAK_DIGEST_ALGOS_FLAG=0
AS_IF([test x"$GPG" != x],
    [AC_MSG_CHECKING([if GnuPG recognizes the --allow-weak-digest-algos flag])
     AS_IF(["$GPG" --allow-weak-digest-algos --version >/dev/null 2>&1],
         [GPG_HAS_ALLOW_WEAK_DIGEST_ALGOS_FLAG=1
          AC_MSG_RESULT([yes])],
         [AC_MSG_RESULT([no])])])
AC_SUBST([GPG_HAS_ALLOW_WEAK_DIGEST_ALGOS_FLAG])

dnl Look for a program that takes a FTP or an HTTP(S) URL as a command line
dnl argument and retrieves the file to the current directory.  Shame we can't
dnl also use "lynx -source"; it only writes to stdout.  ncftp as of version 3
dnl doesn't support this any more (it comes with ncftpget instead), but if
dnl someone has ncftp and not ncftpget, they have an earlier version.
AC_PATH_PROGS([PATH_GETFTP], [wget ncftpget ncftp], [$bindir/simpleftp])
AC_PATH_PROGS([PATH_GETHTTP], [wget], [$bindir/simpleftp])

dnl Checks for libraries.  Use AC_SEARCH_LIBS where possible to avoid
dnl adding libraries when the function is found in libc, and use
dnl INN_SEARCH_AUX_LIBS for libraries that are only used by particular
dnl subsections of INN.

dnl Check for setproctitle in libc first, then libutil if not found there.
dnl We have a replacement function if we can't find it, and then we also need
dnl to check for pstat.
AC_SEARCH_LIBS([setproctitle], [util],
    [AC_DEFINE([HAVE_SETPROCTITLE], [1],
        [Define if you have the setproctitle function.])],
    [AC_LIBOBJ([setproctitle])
     AC_CHECK_FUNCS([pstat])])

dnl The rat's nest of networking libraries.  The common cases are not to
dnl need any extra libraries, or to need -lsocket -lnsl.  We need to avoid
dnl linking with libnsl unless we need it, though, since on some OSes where
dnl it isn't necessary it will totally break networking.  Unisys also
dnl includes gethostbyname in libsocket but needs libnsl for socket().
AC_SEARCH_LIBS([gethostbyname], [nsl])
AC_SEARCH_LIBS([socket], [socket], [],
    [AC_CHECK_LIB([nsl], [socket], [LIBS="$LIBS -lsocket -lnsl"], [],
        [-lsocket])])

dnl Check for inet_aton.  We have our own, but on Solaris the version in
dnl libresolv is more lenient in ways that Solaris's internal DNS resolution
dnl code requires, so if we use our own *and* link with libresolv (which may
dnl be forced by Perl) DNS resolution fails.
AC_SEARCH_LIBS([inet_aton], [resolv])

dnl Search for various additional libraries used by portions of INN.
INN_SEARCH_AUX_LIBS([crypt], [crypt], [CRYPT_LIBS])
INN_SEARCH_AUX_LIBS([getspnam], [shadow], [SHADOW_LIBS])

dnl IRIX has a PAM library with the right symbols but no header files suitable
dnl for use with it, so we have to check the header files first and then only
dnl if one is found do we check for the library.
inn_check_pam=1
AC_CHECK_HEADERS([security/pam_appl.h], [],
    [AC_CHECK_HEADERS([pam/pam_appl.h], [], [inn_check_pam=0])])
if test x"$inn_check_pam" = x1; then
    INN_SEARCH_AUX_LIBS([pam_start], [pam], [PAM_LIBS],
        [AC_DEFINE([HAVE_PAM], [1], [Define if you have PAM.])])
fi
INN_HEADER_PAM_CONST

dnl If keyword generation support was requested, check for the appropriate
dnl libraries.
if test x"$inn_enable_keywords" = x1 ; then
    INN_SEARCH_AUX_LIBS([regexec], [regex], [REGEX_LIBS], [],
        [AC_MSG_ERROR([no usable regular expression library found])])
fi

dnl Handle optional libraries and probing for their locations and component
dnl libraries if needed.
INN_LIB_BDB_OPTIONAL
INN_LIB_BLOCKLIST_OPTIONAL
INN_LIB_CANLOCK_OPTIONAL
INN_LIB_KRB5_OPTIONAL
INN_LIB_OPENSSL_OPTIONAL
INN_LIB_SASL_OPTIONAL
INN_LIB_SQLITE3_OPTIONAL
INN_LIB_SYSTEMD_DAEMON_OPTIONAL
INN_LIB_ZLIB_OPTIONAL

dnl If Kerberos is found, define KRB5_AUTH to auth_krb5 so as to build
dnl that program.
AS_IF([test x"$inn_use_KRB5" = xtrue], [KRB5_AUTH=auth_krb5])
AC_SUBST([KRB5_AUTH])

dnl If Berkeley DB is found, check whether the Berkeley DB library
dnl has ndbm support.
AS_IF([test x"$inn_use_BDB" = xtrue], [INN_LIB_BDB_NDBM])

dnl The dbm libraries are a special case.  If we're building with Berkeley DB,
dnl just use the ndbm support provided by it.
AS_IF([test x"$inn_cv_lib_bdb_ndbm" != xyes],
    [INN_SEARCH_AUX_LIBS([dbm_open], [ndbm dbm gdbm "gdbm_compat -lgdbm"],
         [DBM_LIBS],
         [AC_DEFINE([HAVE_DBM], [1],
              [Define if you have a dbm library.])])
     DBM_CPPFLAGS=],
    [DBM_CPPFLAGS="$BDB_CPPFLAGS"
     DBM_LIBS="$BDB_LDFLAGS $BDB_LIBS"
     AC_SUBST([DBM_LIBS])])
AC_SUBST([DBM_CPPFLAGS])

dnl If SQLite is found, check the presence of its Perl DBI driver.
AS_IF([test x"$inn_use_SQLITE3" = xtrue],
    [INN_PERL_CHECK_MODULE([DBD::SQLite], [],
        [inn_perl_mod_warn="$inn_perl_mod_warn DBD::SQLite"
         inn_perl_mod_warn="$inn_perl_mod_warn (for ovsqlite-util)"])])

dnl If configuring with large file support, determine the right flags to
dnl use based on the platform.
if test x"$inn_enable_largefiles" = xyes ; then
    AC_SYS_LARGEFILE
    AC_DEFINE([DO_LARGEFILES], [1], [Define to use large files.])
fi

dnl Special checks for header files.
AC_HEADER_STDBOOL

dnl Generic checks for header files.
AC_CHECK_HEADERS([crypt.h inttypes.h \
                  stdint.h strings.h sys/bitypes.h sys/filio.h sys/loadavg.h \
                  sys/select.h sys/time.h sys/uio.h syslog.h unistd.h])

dnl Some Linux systems have db1/ndbm.h instead of ndbm.h.  Others have
dnl gdbm/ndbm.h or gdbm-ndbm.h.  Detecting the last two ones is not
dnl straight-forward because Autoconf defines the same preprocessor name
dnl and the same shell variable for them; we therefore have to make sure
dnl the cache is not populated, and to define HAVE_GDBM_SLASH_NDBM_H and
dnl HAVE_GDBM_HYPHEN_NDBM_H separately.
AC_CHECK_HEADERS([ndbm.h db1/ndbm.h], [break])
AS_UNSET([ac_cv_header_gdbm_ndbm_h])
AC_CHECK_HEADER([gdbm/ndbm.h])
AS_IF([test x"$ac_cv_header_gdbm_ndbm_h" != xno],
    [AC_DEFINE([HAVE_GDBM_SLASH_NDBM_H], [1],
         [Define if you have the <gdbm/ndbm.h> header file.])],
    [AS_UNSET([ac_cv_header_gdbm_ndbm_h])
     AC_CHECK_HEADER([gdbm-ndbm.h])
     AS_IF([test x"$ac_cv_header_gdbm_ndbm_h" != xno],
         [AC_DEFINE([HAVE_GDBM_HYPHEN_NDBM_H], [1],
              [Define if you have the <gdbm-ndbm.h> header file.])])])

dnl Check for whether various symbols are declared.
AC_CHECK_DECLS([pread, pwrite, reallocarray, snprintf, setproctitle, strlcat,
                strlcpy, vsnprintf])
AC_CHECK_DECLS([h_errno], [], [], [#include <netdb.h>])
AC_CHECK_DECLS([inet_aton, inet_ntoa], [], [],
    [#include <sys/types.h>
     #include <netinet/in.h>
     #include <arpa/inet.h>])
AC_CHECK_DECLS([altzone], [], [], [#include <time.h>])

dnl Checks for compiler characteristics.
AC_C_BIGENDIAN
AC_C_CONST
INN_C_C99_VAMACROS
INN_C_GNU_VAMACROS

dnl Checks for structures.
AC_STRUCT_TIMEZONE
AC_CHECK_MEMBERS([struct tm.tm_gmtoff])
AC_CHECK_MEMBERS([struct sockaddr.sa_len], [], [],
    [#include <sys/types.h>
     #include <sys/socket.h>])

dnl Checks for types.
AC_TYPE_INT8_T
AC_TYPE_INT16_T
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_UINT8_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_LONG_LONG_INT
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINTPTR_T
AC_FUNC_GETGROUPS
AC_TYPE_UID_T
AC_CHECK_TYPES([sig_atomic_t], [], [],
    [#include <sys/types.h>
     #include <signal.h>])
AC_CHECK_TYPES([socklen_t], [], [],
    [#include <sys/types.h>
     #include <sys/socket.h>])
AC_CHECK_TYPES([union semun], [], [],
    [#include <sys/types.h>
     #include <sys/ipc.h>
     #include <sys/sem.h>])

dnl Enable IPv6 unconditionally if available.
AC_CHECK_TYPES([struct sockaddr_in6],
    [AC_DEFINE([HAVE_INET6], [1],
        [Define to 1 if IPv6 library interfaces are available.])], [],
    [#include <sys/types.h>
     #include <netinet/in.h>])

dnl See if struct sockaddr_storage is available, and if so, how its members
dnl are named.
AC_CHECK_TYPES([struct sockaddr_storage],
    [AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family], [], [],
        [#include <sys/types.h>
         #include <sys/socket.h>])], [],
    [#include <sys/types.h>
     #include <sys/socket.h>])

dnl Checks for macros.
INN_MACRO_IN6_ARE_ADDR_EQUAL
INN_MACRO_IOV_MAX
INN_MACRO_SUN_LEN

dnl Checks for library functions.
INN_FUNC_GETADDRINFO_ADDRCONFIG
INN_FUNC_INET_NTOA
INN_FUNC_SNPRINTF

dnl Check for various other functions.
AC_CHECK_FUNCS(explicit_bzero getloadavg getrusage getspnam \
               setbuffer sigaction \
               setgroups setrlimit setsid socketpair strncasecmp \
               sysconf)

dnl Find a way to get the file descriptor limit.
AC_CHECK_FUNCS([getrlimit getdtablesize ulimit], [break])

dnl Probe for the appropriate stat functions.
AC_CHECK_FUNCS([statvfs], [],
    [AC_CHECK_FUNCS([statfs])
     AC_CHECK_HEADERS([sys/vfs.h sys/param.h])
     AC_CHECK_HEADERS(sys/mount.h, [], [],
         [#ifdef HAVE_SYS_PARAM_H
          # include <sys/param.h>
          #endif
         ])
    ])

dnl If we can't find any of the following, we have replacements for them.
AC_REPLACE_FUNCS(asprintf daemon getaddrinfo getnameinfo getpagesize \
                 inet_aton inet_ntop mkstemp pread pwrite reallocarray \
                 setenv seteuid strcasecmp \
                 strlcat strlcpy strspn strtok symlink)

dnl Probe for fseeko and ftello, which take off_t instead of int.
dnl The logic in portable/system.h is based on the presence of fseeko,
dnl and then for large file support, so keep that order here too.
AC_FUNC_FSEEKO
if test x"$inn_enable_largefiles" = xyes ; then
    AC_CHECK_DECLS([fseeko, ftello])
    if test x"$ac_cv_sys_largefile_source" = xunknown ; then
        INN_TYPE_FPOS_T_LARGE
        AC_LIBOBJ([fseeko])
        AC_LIBOBJ([ftello])
    fi
fi

dnl Probe for mmap properties.
INN_FUNC_MMAP(
    [AC_CHECK_FUNCS([madvise])
     INN_FUNC_MMAP_SEES_WRITES
     INN_FUNC_MMAP_NEEDS_MSYNC
     INN_FUNC_MSYNC_ARGS])

dnl Probes for system characteristics.
INN_SYS_STREAMS_SENDFD
INN_SYS_UNIX_SOCKETS
INN_LOG_FACILITY

dnl Probes for flags recognized by the compiler when building with warnings.
dnl Default to including all of the generally useful warnings unless there's
dnl something that makes them unsuitable.  In particular, the following
dnl warnings are *not* included for gcc:
dnl
dnl   -ansi                 Requires messing with feature test macros.
dnl   -Wpedantic            Too much noise from embedded Perl.
dnl   -Wdouble-promotion    Too much noise from using printf with floats.
dnl   -Wswitch-default      Quite annoying to enforce it.
dnl   -Wstrict-overflow=2   Gives false positives.
dnl   -Wtraditional         We assume ANSI C, so these aren't interesting.
dnl   -Wtraditional-conversion
dnl                         Warns about problems when upgrading from K&R to
dnl                         ANSI C, so these aren't interesting.
dnl   -Wundef               We need portability code.
dnl   -Wformat-truncation=2 Gives (many) false positives with GCC 10.2.1
dnl                         https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83011
dnl   -Wswitch-enum         Useless noise.
dnl   -Wunsafe-loop-optimizations
dnl                         Too much noise.
dnl   -Wcast-qual           Used for a while, but some casts are unavoidable.
dnl   -Wconversion          Too much noise, even with -Wno-sign-conversion.
dnl   -Waggregate-return    Syntax allowed in C.
dnl   -Wmissing-noreturn    Not necessary (unless for optimization).
dnl   -Wpacked              Used by INN.
dnl   -Wpadded              Used by INN.
dnl   -Wlong-long           Too much noise from system headers.
dnl   -Woverlength-strings  Useless noise.
dnl   -Wunused-function     Noise from embedded Perl (at least with Perl 5.20).
dnl
dnl Some may be worth looking at again once a released version of gcc doesn't
dnl warn on system headers.  The warnings below are in the same order as
dnl they're listed in the gcc manual.
dnl
dnl Last checked against gcc 13.2 (2024-01-26).
dnl
dnl Add -g because when building with warnings, one generally also wants the
dnl debugging information, and add -O3 because gcc won't find some warnings
dnl without optimization turned on.  Add -DDEBUG=1 so that we'll also
dnl compile all debugging code and check it as well.
dnl
dnl -D_FORTIFY_SOURCE=2 (set as an hardening flag) enables warn_unused_result
dnl attribute markings on glibc functions on Linux, as well as more object size
dnl checking, which catches a few more issues.
dnl
dnl For Clang, try -Weverything but disable some of the warnings:
dnl
dnl   -Wcast-qual                     Some structs require casting away const.
dnl   -Wcovered-switch-default        Does not do harm to have default cases.
dnl   -Wdisabled-macro-expansion      Not an actual problem.
dnl   -Wexcess-padding                Not an actual problem.
dnl   -Wextra-semi-stmt               Useful for readability.
dnl   -Wpacked                        Not an actual problem.
dnl   -Wpadded                        Not an actual problem.
dnl   -Wpoison-system-directories     Not an actual problem (e.g. Xcode).
dnl   -Wreserved-id-macro             Autoconf sets several of these normally.
dnl   -Wreserved-identifier           False positives with FD_ZERO.
dnl   -Wsign-conversion               Too many fiddly changes for the benefit.
dnl   -Wstack-protector-purecap-ignored Not an actual problem (CHERI hardware).
dnl   -Wswitch-default                Not an actual problem.
dnl   -Wswitch-enum                   Useless noise.
dnl   -Wtautological-pointer-compare  False positives with for loops.
dnl   -Wundef                         Conflicts with Autoconf probe results.
dnl   -Wunreachable-code              Happens with optional compilation.
dnl   -Wunreachable-code-return       Other compilers get confused.
dnl   -Wunsafe-buffer-usage           Intended for C++, not applicable to C.
dnl   -Wunused-macros                 Conflicts with flex macros.
dnl   -Wused-but-marked-unused        Happens a lot with conditional code.
dnl
dnl It would be worthwhile trying to enforce the following checks:
dnl "-Wconversion -Wno-sign-conversion" (for gcc)
dnl -Wstack-protector (for gcc, but many false positives from small buffers)
dnl -Wimplicit-int-conversion, -Wshorten-64-to-32 (for Clang)
dnl -fstrict-overflow (for Clang, but -fwrapv used by embedded Perl causes an
dnl error of "argument unused during compilation" in clang-11)
dnl
dnl First, we add -Wunknown-warning-option to CFLAGS so that Clang properly
dnl reports probes for unknown flags as errors.
INN_PROG_CC_FLAG([-Werror=unknown-warning-option],
                 [CFLAGS="$CFLAGS -Werror=unknown-warning-option"], [])
m4_foreach_w(
    [flag],
    [-fstrict-aliasing -fstrict-flex-arrays=3
     -g -O3 -DDEBUG=1 -Werror -Wall -Wextra -Wdouble-promotion -Wformat=2
     -Wformat-overflow=2 -Wformat-signedness -Wformat-truncation=1
     -Wnull-dereference -Winit-self
     -Wmissing-include-dirs -Wshift-overflow=2
     -Wsync-nand -Wstringop-overflow=4 -Wstringop-truncation
     -Wmissing-format-attribute
     -Walloc-zero -Walloca -Warith-conversion -Warray-bounds=3
     -Wattribute-alias=2 -Wduplicated-branches -Wduplicated-cond
     -Wtrampolines -Wfloat-equal -Wdeclaration-after-statement -Wshadow
     -Wpointer-arith -Wc99-c11-compat
     -Wbad-function-cast -Wcast-align=strict -Wwrite-strings
     -Wdangling-else -Wdate-time
     -Wjump-misses-init -Wlogical-op -Wstrict-prototypes
     -Wold-style-definition
     -Wmissing-prototypes -Wmissing-declarations
     -Wnormalized=nfc -Wredundant-decls -Wrestrict -Wnested-externs -Winline
     -Winvalid-pch -Wvla -Wuse-after-free=3 -Wno-unused-function
     -Weverything -Wno-cast-qual -Wno-covered-switch-default
     -Wno-disabled-macro-expansion -Wno-excess-padding -Wno-extra-semi-stmt
     -Wno-implicit-int-conversion -Wno-packed -Wno-padded
     -Wno-poison-system-directories
     -Wno-reserved-id-macro -Wno-reserved-identifier -Wno-shorten-64-to-32
     -Wno-sign-conversion -Wno-stack-protector-purecap-ignored
     -Wno-switch-default -Wno-switch-enum
     -Wno-tautological-pointer-compare
     -Wno-undef -Wno-unreachable-code -Wno-unreachable-code-return
     -Wno-unsafe-buffer-usage
     -Wno-unused-macros -Wno-used-but-marked-unused],
    [INN_PROG_CC_FLAG(flag, [CC_WARNINGS="${CC_WARNINGS} flag"], [])])
AC_SUBST([CC_WARNINGS])

dnl On OpenBSD, the system headers contain many redundant declarations.
AS_CASE([$host],
    [*-openbsd*],
        [CC_WARNINGS=`AS_ECHO(["${CC_WARNINGS}"]) | sed 's/-Wredundant-decls //'`])

dnl Add hardening build flags, if supported by the compiler.
dnl Solaris has a separate libssp, so -fstack-protector-strong also has
dnl to be passed to the linker.  And we assume that if the linker does not
dnl accept -fstack-protector-strong, the build is likely to fail (like on AIX
dnl where libssp_nonshared may not be present).
AS_IF([test x"$inn_enable_hardening_flags" = xyes],
    [INN_PROG_CC_FLAG([-fPIE], [CFLAGS="${CFLAGS} -fPIE"
                                CC_WARNINGS="${CC_WARNINGS} -fPIE"
                                INN_PROG_LD_FLAG([-pie],
                                    [LDFLAGS="${LDFLAGS} -pie"], [])])
     INN_PROG_CC_FLAG([-D_FORTIFY_SOURCE=2],
                      [CFLAGS="${CFLAGS} -D_FORTIFY_SOURCE=2"
                       CC_WARNINGS="${CC_WARNINGS} -D_FORTIFY_SOURCE=2"],
                      [])
     INN_PROG_CC_FLAG([-fstack-protector-strong],
                      [CFLAGS="${CFLAGS} -fstack-protector-strong"
                       CC_WARNINGS="${CC_WARNINGS} -fstack-protector-strong"],
                      [])
     INN_PROG_LD_FLAG([-fstack-protector-strong],
                      [LDFLAGS="${LDFLAGS} -fstack-protector-strong"],
                      [CFLAGS=`AS_ECHO(["${CFLAGS}"]) | sed 's/ -fstack-protector-strong//'`
                       CC_WARNINGS=`AS_ECHO(["${CC_WARNINGS}"]) | sed 's/ -fstack-protector-strong//'`])
     INN_PROG_LD_FLAG([-Wl,-z,relro],
                      [LDFLAGS="${LDFLAGS} -Wl,-z,relro"], [])
     INN_PROG_LD_FLAG([-Wl,-z,now],
                      [LDFLAGS="${LDFLAGS} -Wl,-z,now"], [])])

dnl Now that compiler flags have been checked, remove -Wunknown-warning-option
dnl from CFLAGS.
CFLAGS=`AS_ECHO(["${CFLAGS}"]) | sed 's/ -Werror=unknown-warning-option//'`

dnl Clean up our LIBS, just for grins.
LIBS=`AS_ECHO(["$LIBS"]) | sed 's/^  *//' | sed 's/   */ /g' | sed 's/  *$//'`

dnl Configure our output files.  Try to keep this as limited as possible,
dnl since it directly affects how long it takes configure to complete.
AC_CONFIG_FILES([Makefile.global include/inn/paths.h])
AC_CONFIG_FILES([scripts/innshellvars scripts/innshellvars.tcl])
AC_CONFIG_FILES([perl/INN/Config.pm scripts/innshellvars.pl])
AC_CONFIG_FILES([support/fixconfig], [chmod +x support/fixconfig])
AC_CONFIG_FILES([support/fixscript], [chmod +x support/fixscript])

dnl Include some additional files at the beginning of config.h.
AH_TOP([/* Include a few useful functions and macros. */
#include "inn/macros.h"
#include "inn/options.h"
#include "inn/system.h"
#include "portable/stdbool.h"])

dnl Most configuration information goes here.
AC_CONFIG_HEADERS([include/config.h])

dnl Generate the configure output.
AC_OUTPUT

dnl Print out some additional information on what to check.
cat <<EOM

Please check the following files before running make, to ensure that
everything was set correctly.

        Makefile.global
        include/config.h
        include/inn/options.h
        include/inn/paths.h
        innfeed/innfeed.h

EOM

dnl Write a warning for missing Perl modules at the end of the output.
dnl $inn_perl_mod_warn already has a leading space.
if test x"$inn_perl_mod_warn" != x ; then
    echo "Missing Perl module(s): $inn_perl_mod_warn."
    echo "You should install them for these programs to work fine."
fi

dnl Finally, double-check the configured temporary directory.  Some people
dnl point this at the system temporary directories or at other world-writeable
dnl directories, which can be a local security hole.
if $PERL -e "exit((stat('$PATH_TMP'))[[2]] & 2)" > /dev/null ; then
    :
else
    cat <<EOM

WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING

  The temporary directory you have configured is world-writeable.  It is
  currently set to $tmpdir.

  This directory is used by INN for temporary files and should only be
  writeable by the news user.  INN does not go to great lengths to prevent
  symlink attacks and the like because it assumes this directory is not
  world-writeable.  By configuring INN in this fashion, you may be
  introducing a locally exploitable security hole.

  It is STRONGLY recommended that you use a temporary directory reserved for
  INN's exclusive use, one which is not world-writeable.  You can do this
  either with --with-tmp-dir or by setting --prefix to something other than
  /usr or /.

EOM
fi
