--- /dev/null
+fix_ad_flag
+fix_body_regexps
+nocem-gpg-import
+debian-paths
+configure-hostname
+no-makedbz-on-install
+u_innreport_misc
+u_right_length
+u_status_init_ip
+u_tls_duplicate_reply
+u_xhdr_permissions
+u_xover_duplicate_reply
+typo_inn_conf_man
--- /dev/null
+#! /bin/sh
+
+# From configure.in Revision: 7466
+# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*-
+## Copyright 1996, 1997, 1998, 1999, 2000, 2001
+## Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## 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.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 46 AC_PROG_LIBTOOL
+
+
+
+
+
+# AC_LIBTOOL_HEADER_ASSERT
+# ------------------------
+# AC_LIBTOOL_HEADER_ASSERT
+
+# _LT_AC_CHECK_DLFCN
+# --------------------
+# _LT_AC_CHECK_DLFCN
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+ # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+# ---------------------------------
+# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+# _LT_AC_PROG_ECHO_BACKSLASH
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ------------------------------------------------------------------
+# _LT_AC_TRY_DLOPEN_SELF
+
+# AC_LIBTOOL_DLOPEN_SELF
+# -------------------
+# AC_LIBTOOL_DLOPEN_SELF
+
+# _LT_AC_LTCONFIG_HACK
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+
+
+# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install
+
+
+# AC_LIBTOOL_PICMODE - implement the --with-pic flag
+# Usage: AC_LIBTOOL_PICMODE[(MODE)]
+# Where MODE is either `yes' or `no'. If omitted, it defaults to
+# `both'.
+
+
+
+# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library
+
+
+
+# AC_PATH_MAGIC - find a file program which can recognise a shared library
+
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+
+
+# AC_PROG_LD_GNU -
+
+
+# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+
+
+# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+
+
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+
+
+# AC_CHECK_LIBM - check for math library
+
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments. Note that LIBLTDL and INCLTDL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
+# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
+# with '${top_builddir}/' and INCLTDL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!). If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
+# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!). If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+
+
+# old names
+
+
+
+
+
+
+
+
+# This is just to silence aclocal about the macro not being used
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_default_prefix=/usr/local/news
+ac_help="$ac_help
+ --enable-libtool Use libtool for lib generation [default=no]"
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+
+# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) lt_cv_sys_path_separator=';' ;;
+ *) lt_cv_sys_path_separator=':' ;;
+ esac
+ PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+ ;;
+esac
+
+echo=${ECHO-echo}
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+
+EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+ then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ echo='printf %s\n'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+ac_help="$ac_help
+ --disable-libtool-lock avoid locking (might break parallel builds)"
+ac_help="$ac_help
+ --with-pic try to use only PIC/non-PIC objects [default=use both]"
+ac_help="$ac_help
+ --with-control-dir=PATH Path for control programs [PREFIX/bin/control]"
+ac_help="$ac_help
+ --with-db-dir=PATH Path for news database files [PREFIX/db]"
+ac_help="$ac_help
+ --with-doc-dir=PATH Path for news documentation [PREFIX/doc]"
+ac_help="$ac_help
+ --with-etc-dir=PATH Path for news config files [PREFIX/etc]"
+ac_help="$ac_help
+ --with-filter-dir=PATH Path for embedded filters [PREFIX/bin/filter]"
+ac_help="$ac_help
+ --with-lib-dir=PATH Path for news library files [PREFIX/lib]"
+ac_help="$ac_help
+ --with-log-dir=PATH Path for news logs [PREFIX/log]"
+ac_help="$ac_help
+ --with-run-dir=PATH Path for news PID/runtime files [PREFIX/run]"
+ac_help="$ac_help
+ --with-spool-dir=PATH Path for news storage [PREFIX/spool]"
+ac_help="$ac_help
+ --with-tmp-dir=PATH Path for temporary files [PREFIX/tmp]"
+ac_help="$ac_help
+ --with-syslog-facility=LOG_FAC Syslog facility [LOG_NEWS or LOG_LOCAL1]"
+ac_help="$ac_help
+ --with-news-user=USER News user name [news]"
+ac_help="$ac_help
+ --with-news-group=GROUP News group name [news]"
+ac_help="$ac_help
+ --with-news-master=USER News master (address for reports) [usenet]"
+ac_help="$ac_help
+ --with-news-umask=UMASK umask for news files [002]"
+ac_help="$ac_help
+ --enable-setgid-inews Install inews setgid"
+ac_help="$ac_help
+ --enable-uucp-rnews Install rnews setuid, group uucp"
+ac_help="$ac_help
+ --with-log-compress=METHOD Log compression method [gzip]"
+ac_help="$ac_help
+ --with-innd-port=PORT Additional low-numbered port for inndstart"
+ac_help="$ac_help
+ --enable-ipv6 Enable IPv6 support"
+ac_help="$ac_help
+ --with-max-sockets=N Maximum number of listening sockets in innd"
+ac_help="$ac_help
+ --enable-tagged-hash Use tagged hash table for history"
+ac_help="$ac_help
+ --enable-keywords Automatic keyword generation support"
+ac_help="$ac_help
+ --enable-largefiles Support for files larger than 2GB [default=no]"
+ac_help="$ac_help
+ --with-sendmail=PATH Path to sendmail"
+ac_help="$ac_help
+ --with-kerberos=PATH Path to Kerberos v5 (for auth_krb5)"
+ac_help="$ac_help
+ --with-perl Embedded Perl script support [default=no]"
+ac_help="$ac_help
+ --with-python Embedded Python module support [default=no]"
+ac_help="$ac_help
+ --with-berkeleydb[=PATH] Enable BerkeleyDB (for ovdb overview method)"
+ac_help="$ac_help
+ --with-openssl=PATH Enable OpenSSL (for NNTP over SSL support)"
+ac_help="$ac_help
+ --with-sasl=PATH Enable SASL (for imapfeed authentication)"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=Makefile.global.in
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in support $srcdir/support; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in support $srcdir/support" 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+
+test x"$prefix" = xNONE && prefix="$ac_default_prefix"
+
+builddir=`pwd`
+
+
+if test x"$with_largefiles" != x ; then
+ { echo "configure: error: Use --enable-largefiles instead of --with-largefiles" 1>&2; exit 1; }
+fi
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:966: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:996: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1047: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1079: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1090 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1095: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1121: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1126: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1135: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1154: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1186: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1201 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1207: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1218 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1224: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1235 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1241: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for AIX""... $ac_c" 1>&6
+echo "configure:1266: checking for AIX" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1268 "configure"
+#include "confdefs.h"
+#ifdef _AIX
+ yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF
+#define _ALL_SOURCE 1
+EOF
+
+else
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:1290: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+echo $ac_n "checking for object suffix""... $ac_c" 1>&6
+echo "configure:1311: checking for object suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftest*
+echo 'int i = 1;' > conftest.$ac_ext
+if { (eval echo configure:1317: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+else
+ { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_objext" 1>&6
+OBJEXT=$ac_cv_objext
+ac_objext=$ac_cv_objext
+
+
+echo $ac_n "checking if $CC supports -c -o file.$ac_objext""... $ac_c" 1>&6
+echo "configure:1336: checking if $CC supports -c -o file.$ac_objext" >&5
+if eval "test \"`echo '$''{'inn_cv_compiler_c_o'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+echo "int some_variable = 0;" > conftest.$ac_ext
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory. Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+compiler_c_o=no
+if { (eval $ac_compile) 2> out/conftest.err; } \
+ && test -s out/conftest2.$ac_objext; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+ inn_cv_compiler_c_o=no
+ else
+ inn_cv_compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat out/conftest.err 1>&5
+ inn_cv_compiler_c_o=no
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+rm -f conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+rm -f -r conftest 2>/dev/null
+fi
+
+compiler_c_o=$inn_cv_compiler_c_o
+echo "$ac_t""$compiler_c_o" 1>&6
+
+inn_use_libtool=no
+# Check whether --enable-libtool or --disable-libtool was given.
+if test "${enable_libtool+set}" = set; then
+ enableval="$enable_libtool"
+ if test "$enableval" = yes ; then
+ inn_use_libtool=yes
+ fi
+fi
+
+if test x"$inn_use_libtool" = xyes ; then
+ # Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) lt_cv_sys_path_separator=';' ;;
+ *) lt_cv_sys_path_separator=':' ;;
+ esac
+ PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:1402: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1407 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:1418: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:1435: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1440 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:1447: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1539: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:1560: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1589: checking for ld used by GCC" >&5
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1619: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1622: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1657: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ lt_cv_prog_gnu_ld=yes
+else
+ lt_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6
+echo "configure:1674: checking for $LD option to reload object files" >&5
+if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+
+echo "$ac_t""$lt_cv_ld_reload_flag" 1>&6
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1686: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/${ac_tool_prefix}nm
+ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ else
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+
+NM="$lt_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1724: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6
+echo "configure:1745: checking how to recognise dependant libraries" >&5
+if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin* | mingw* | pw32*)
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.[012])
+ lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1`
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ ;;
+
+freebsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20*|hpux11*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+
+irix5* | irix6*)
+ case $host_os in
+ irix5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ case $host_cpu in
+ alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* )
+ lt_cv_deplibs_check_method=pass_all ;;
+ *)
+ # glibc up to 2.1.1 does not perform some relocations on ARM
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+openbsd*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+ else
+ lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+sysv5uw[78]* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+echo "$ac_t""$lt_cv_deplibs_check_method" 1>&6
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:1930: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:1940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.$ac_ext | *.c | *.o | *.obj) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output""... $ac_c" 1>&6
+echo "configure:1971: checking command to parse $NM output" >&5
+if eval "test \"`echo '$''{'lt_cv_sys_global_symbol_pipe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ ;;
+irix*)
+ symcode='[BCDEGRST]'
+ ;;
+solaris* | sysv5*)
+ symcode='[BDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $host_os in
+mingw*)
+ opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Write the raw and C identifiers.
+lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+ rm -f conftest*
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ if { (eval echo configure:2051: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { (eval echo configure:2054: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext'
+
+ cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext
+ cat <<\EOF >> conftest.$ac_ext
+ {0, (lt_ptr) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo configure:2105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ pipe_works=yes
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -f conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+global_symbol_pipe="$lt_cv_sys_global_symbol_pipe"
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ global_symbol_to_cdecl=
+ global_symbol_to_c_name_address=
+else
+ global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl"
+ global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address"
+fi
+if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
+then
+ echo "$ac_t""failed" 1>&6
+else
+ echo "$ac_t""ok" 1>&6
+fi
+
+for ac_hdr in dlfcn.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2154: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2159 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2164: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6
+echo "configure:2199: checking for ${ac_tool_prefix}file" >&5
+if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$ac_t""$MAGIC_CMD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ echo $ac_n "checking for file""... $ac_c" 1>&6
+echo "configure:2261: checking for file" >&5
+if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$ac_t""$MAGIC_CMD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2332: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2364: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ RANLIB=":"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2399: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+ echo "$ac_t""$STRIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_STRIP"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2431: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_STRIP="strip"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+ echo "$ac_t""$STRIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ STRIP=":"
+fi
+fi
+
+
+enable_dlopen=no
+enable_win32_dll=no
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ :
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 2480 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:2481: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:2502: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ cat > conftest.$ac_ext <<EOF
+#line 2515 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2522: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+ ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+need_locks="$enable_libtool_lock"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+if test x"$host" != x"$build"; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case $host_os in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+ ;;
+ *)
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+## FIXME: this should be a separate macro
+##
+echo $ac_n "checking for objdir""... $ac_c" 1>&6
+echo "configure:2644: checking for objdir" >&5
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t""$objdir" 1>&6
+##
+## END FIXME
+
+
+## FIXME: this should be a separate macro
+##
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+ withval="$with_pic"
+ pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+test -z "$pic_mode" && pic_mode=default
+
+# We assume here that the value for lt_cv_prog_cc_pic will not be cached
+# in isolation, and that seeing it set (from the cache) indicates that
+# the associated values are set (in the cache) correctly too.
+echo $ac_n "checking for $compiler option to produce PIC""... $ac_c" 1>&6
+echo "configure:2675: checking for $compiler option to produce PIC" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_cc_pic'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_prog_cc_pic=
+ lt_cv_prog_cc_shlib=
+ lt_cv_prog_cc_wl=
+ lt_cv_prog_cc_static=
+ lt_cv_prog_cc_no_builtin=
+ lt_cv_prog_cc_can_build_shared=$can_build_shared
+
+ if test "$GCC" = yes; then
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-static'
+
+ case $host_os in
+ aix*)
+ # Below there is a dirty hack to force normal static linking with -ldl
+ # The problem is because libdl dynamically linked with both libc and
+ # libC (AIX C++ library), which obviously doesn't included in libraries
+ # list by gcc. This cause undefined symbols with -static flags.
+ # This hack allows C programs to be linked with "-static -ldl", but
+ # not sure about C++ programs.
+ lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC"
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_cv_prog_cc_pic='-fno-common'
+ ;;
+ cygwin* | mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_cv_prog_cc_pic='-DDLL_EXPORT'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_cv_prog_cc_pic=-Kconform_pic
+ fi
+ ;;
+ *)
+ lt_cv_prog_cc_pic='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for PIC flags for the system compiler.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ lt_cv_prog_cc_wl='-Wl,'
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_cv_prog_cc_static='-Bstatic'
+ else
+ lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ # Is there a better lt_cv_prog_cc_static that works with the bundled CC?
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive"
+ lt_cv_prog_cc_pic='+Z'
+ ;;
+
+ irix5* | irix6*)
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ cygwin* | mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_cv_prog_cc_pic='-DDLL_EXPORT'
+ ;;
+
+ newsos6)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ # All OSF/1 code is PIC.
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ lt_cv_prog_cc_pic='-Kpic'
+ lt_cv_prog_cc_static='-dn'
+ lt_cv_prog_cc_shlib='-belf'
+ ;;
+
+ solaris*)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ lt_cv_prog_cc_wl='-Wl,'
+ ;;
+
+ sunos4*)
+ lt_cv_prog_cc_pic='-PIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ lt_cv_prog_cc_wl='-Qoption ld '
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ if test "x$host_vendor" = xsni; then
+ lt_cv_prog_cc_wl='-LD'
+ else
+ lt_cv_prog_cc_wl='-Wl,'
+ fi
+ ;;
+
+ uts4*)
+ lt_cv_prog_cc_pic='-pic'
+ lt_cv_prog_cc_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_cv_prog_cc_pic='-Kconform_pic'
+ lt_cv_prog_cc_static='-Bstatic'
+ fi
+ ;;
+
+ *)
+ lt_cv_prog_cc_can_build_shared=no
+ ;;
+ esac
+ fi
+
+fi
+
+if test -z "$lt_cv_prog_cc_pic"; then
+ echo "$ac_t""none" 1>&6
+else
+ echo "$ac_t""$lt_cv_prog_cc_pic" 1>&6
+
+ # Check to make sure the pic_flag actually works.
+ echo $ac_n "checking if $compiler PIC flag $lt_cv_prog_cc_pic works""... $ac_c" 1>&6
+echo "configure:2827: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5
+ if eval "test \"`echo '$''{'lt_cv_prog_cc_pic_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
+ cat > conftest.$ac_ext <<EOF
+#line 2834 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2841: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ case $host_os in
+ hpux9* | hpux10* | hpux11*)
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then
+ # they create non-PIC objects. So, if there were any warnings, we
+ # assume that PIC is not supported.
+ if test -s conftest.err; then
+ lt_cv_prog_cc_pic_works=no
+ else
+ lt_cv_prog_cc_pic_works=yes
+ fi
+ ;;
+ *)
+ lt_cv_prog_cc_pic_works=yes
+ ;;
+ esac
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_prog_cc_pic_works=no
+
+fi
+rm -f conftest*
+ CFLAGS="$save_CFLAGS"
+
+fi
+
+
+ if test "X$lt_cv_prog_cc_pic_works" = Xno; then
+ lt_cv_prog_cc_pic=
+ lt_cv_prog_cc_can_build_shared=no
+ else
+ lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
+ fi
+
+ echo "$ac_t""$lt_cv_prog_cc_pic_works" 1>&6
+fi
+##
+## END FIXME
+
+# Check for any special shared library compilation flags.
+if test -n "$lt_cv_prog_cc_shlib"; then
+ echo "configure: warning: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" 1>&2
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]" >/dev/null; then :
+ else
+ echo "configure: warning: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" 1>&2
+ lt_cv_prog_cc_can_build_shared=no
+ fi
+fi
+
+## FIXME: this should be a separate macro
+##
+echo $ac_n "checking if $compiler static flag $lt_cv_prog_cc_static works""... $ac_c" 1>&6
+echo "configure:2897: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_cc_static_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_prog_cc_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
+ cat > conftest.$ac_ext <<EOF
+#line 2905 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2912: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_prog_cc_static_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+
+
+# Belt *and* braces to stop my trousers falling down:
+test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
+echo "$ac_t""$lt_cv_prog_cc_static_works" 1>&6
+
+pic_flag="$lt_cv_prog_cc_pic"
+special_shlib_compile_flags="$lt_cv_prog_cc_shlib"
+wl="$lt_cv_prog_cc_wl"
+link_static_flag="$lt_cv_prog_cc_static"
+no_builtin_flag="$lt_cv_prog_cc_no_builtin"
+can_build_shared="$lt_cv_prog_cc_can_build_shared"
+##
+## END FIXME
+
+
+## FIXME: this should be a separate macro
+##
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.$ac_objext""... $ac_c" 1>&6
+echo "configure:2943: checking if $compiler supports -c -o file.$ac_objext" >&5
+if eval "test \"`echo '$''{'lt_cv_compiler_c_o'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+echo "int some_variable = 0;" > conftest.$ac_ext
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory. Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+compiler_c_o=no
+if { (eval echo configure:2962: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+ lt_cv_compiler_c_o=no
+ else
+ lt_cv_compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat out/conftest.err 1>&5
+ lt_cv_compiler_c_o=no
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+fi
+
+compiler_c_o=$lt_cv_compiler_c_o
+echo "$ac_t""$compiler_c_o" 1>&6
+
+if test x"$compiler_c_o" = x"yes"; then
+ # Check to see if we can write to a .lo
+ echo $ac_n "checking if $compiler supports -c -o file.lo""... $ac_c" 1>&6
+echo "configure:2991: checking if $compiler supports -c -o file.lo" >&5
+ if eval "test \"`echo '$''{'lt_cv_compiler_o_lo'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ lt_cv_compiler_o_lo=no
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -c -o conftest.lo"
+ save_objext="$ac_objext"
+ ac_objext=lo
+ cat > conftest.$ac_ext <<EOF
+#line 3002 "configure"
+#include "confdefs.h"
+
+int main() {
+int some_variable = 0;
+; return 0; }
+EOF
+if { (eval echo configure:3009: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ lt_cv_compiler_o_lo=no
+ else
+ lt_cv_compiler_o_lo=yes
+ fi
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ ac_objext="$save_objext"
+ CFLAGS="$save_CFLAGS"
+
+fi
+
+ compiler_o_lo=$lt_cv_compiler_o_lo
+ echo "$ac_t""$compiler_o_lo" 1>&6
+else
+ compiler_o_lo=no
+fi
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ echo $ac_n "checking if we can lock with hard links""... $ac_c" 1>&6
+echo "configure:3044: checking if we can lock with hard links" >&5
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ echo "$ac_t""$hard_links" 1>&6
+ if test "$hard_links" = no; then
+ echo "configure: warning: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" 1>&2
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+if test "$GCC" = yes; then
+ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+ echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions""... $ac_c" 1>&6
+echo "configure:3067: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
+ compiler_rtti_exceptions=no
+ cat > conftest.$ac_ext <<EOF
+#line 3073 "configure"
+#include "confdefs.h"
+
+int main() {
+int some_variable = 0;
+; return 0; }
+EOF
+if { (eval echo configure:3080: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ compiler_rtti_exceptions=no
+ else
+ compiler_rtti_exceptions=yes
+ fi
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ CFLAGS="$save_CFLAGS"
+ echo "$ac_t""$compiler_rtti_exceptions" 1>&6
+
+ if test "$compiler_rtti_exceptions" = "yes"; then
+ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+ else
+ no_builtin_flag=' -fno-builtin'
+ fi
+fi
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries""... $ac_c" 1>&6
+echo "configure:3111: checking whether the linker ($LD) supports shared libraries" >&5
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+old_archive_from_expsyms_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_into_libs=no
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+link_all_deplibs=unknown
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced. Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+extract_expsyms_cmds=
+
+case $host_os in
+cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ # On AIX, the GNU linker is very broken
+ # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available.
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can use
+ # them.
+ ld_shlibs=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+
+ extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
+ sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~
+ test -f $output_objdir/impgen.exe || (cd $output_objdir && \
+ if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
+ else $CC -o impgen impgen.c ; fi)~
+ $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
+
+ old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
+
+ # cygwin and mingw dlls have different entry points and sets of symbols
+ # to exclude.
+ # FIXME: what about values for MSVC?
+ dll_entry=__cygwin_dll_entry@12
+ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
+ case $host_os in
+ mingw*)
+ # mingw values
+ dll_entry=_DllMainCRTStartup@12
+ dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
+ ;;
+ esac
+
+ # mingw and cygwin differ, and it's simplest to just exclude the union
+ # of the two symbol sets.
+ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one (in ltdll.c)
+ if test "x$lt_cv_need_dllmain" = "xyes"; then
+ ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext "
+ ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~
+ test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
+ else
+ ltdll_obj=
+ ltdll_cmds=
+ fi
+
+ # Extract the symbol export list from an `--export-all' def file,
+ # then regenerate the def file from the symbol export list, so that
+ # the compiled dll only exports the symbol export list.
+ # Be careful not to strip the DATA tag left be newer dlltools.
+ export_symbols_cmds="$ltdll_cmds"'
+ $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
+ sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
+
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is.
+ # If DATA tags from a recent dlltool are present, honour them!
+ archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname-def;
+ else
+ echo EXPORTS > $output_objdir/$soname-def;
+ _lt_hint=1;
+ cat $export_symbols | while read symbol; do
+ set dummy \$symbol;
+ case \$# in
+ 2) echo " \$2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
+ *) echo " \$2 @ \$_lt_hint \$3 ; " >> $output_objdir/$soname-def;;
+ esac;
+ _lt_hint=`expr 1 + \$_lt_hint`;
+ done;
+ fi~
+ '"$ltdll_cmds"'
+ $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
+ $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
+ $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris* | sysv5*)
+ if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+ elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = yes; then
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ case $host_os in
+ cygwin* | mingw* | pw32*)
+ # dlltool doesn't understand --whole-archive et. al.
+ whole_archive_flag_spec=
+ ;;
+ *)
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ ;;
+ esac
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ hardcode_direct=yes
+ archive_cmds=''
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ hardcode_direct=yes
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ esac
+
+ shared_flag='-shared'
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ shared_flag='${wl}-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ # It seems that -bexpall can do strange things, so it is better to
+ # generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
+ archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ else
+ hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib'
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='${wl}-berok'
+ # This is a bit strange, but is similar to how AIX traditionally builds
+ # it's shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ ;;
+
+ darwin* | rhapsody*)
+ case "$host_os" in
+ rhapsody* | darwin1.[012])
+ allow_undefined_flag='-undefined suppress'
+ ;;
+ *) # Darwin 1.3 on
+ allow_undefined_flag='-flat_namespace -undefined suppress'
+ ;;
+ esac
+ # FIXME: Relying on posixy $() will cause problems for
+ # cross-compilation, but unfortunately the echo tests do not
+ # yet detect zsh echo's removal of \ escapes.
+ archive_cmds='$nonopt $(test "x$module" = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
+ # We need to add '_' to the symbols in $export_symbols first
+ #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ whole_archive_flag_spec='-all_load $convenience'
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ case $host_os in
+ hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
+ *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
+ esac
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_minus_L=yes # Not in the search PATH, but as the default
+ # location of the library.
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+ #Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ ;;
+
+ solaris*)
+ # gcc --version < 3.0 without binutils cannot create self contained
+ # shared libraries reliably, requiring libgcc.a to resolve some of
+ # the object symbols generated in some cases. Libraries that use
+ # assert need libgcc.a to resolve __eprintf, for example. Linking
+ # a copy of libgcc.a into every shared library to guarantee resolving
+ # such symbols causes other problems: According to Tim Van Holder
+ # <tim.van.holder@pandora.be>, C++ libraries end up with a separate
+ # (to the application) exception stack for one thing.
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ case `$CC --version 2>/dev/null` in
+ [12].*)
+ cat <<EOF 1>&2
+
+*** Warning: Releases of GCC earlier than version 3.0 cannot reliably
+*** create self contained shared libraries on Solaris systems, without
+*** introducing a dependency on libgcc.a. Therefore, libtool is disabling
+*** -no-undefined support, which will at least allow you to build shared
+*** libraries. However, you may find that when you link such libraries
+*** into an application without using GCC, you have to manually add
+*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to
+*** upgrade to a newer version of GCC. Another option is to rebuild your
+*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer.
+
+EOF
+ no_undefined_flag=
+ ;;
+ esac
+ fi
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ if test "x$host_vendor" = xsno; then
+ archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ else
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv5*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ hardcode_libdir_flag_spec=
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4.2uw2*)
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ hardcode_runpath_var=yes
+ runpath_var=LD_RUN_PATH
+ ;;
+
+ sysv5uw7* | unixware7*)
+ no_undefined_flag='${wl}-z ${wl}text'
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+echo "$ac_t""$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs""... $ac_c" 1>&6
+echo "configure:3799: checking how to hardcode library paths into programs" >&5
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$hardcode_shlibpath_var" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+echo "$ac_t""$hardcode_action" 1>&6
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+striplib=
+old_striplib=
+echo $ac_n "checking whether stripping libraries is possible""... $ac_c" 1>&6
+echo "configure:3831: checking whether stripping libraries is possible" >&5
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+##
+## END FIXME
+
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+## FIXME: this should be a separate macro
+##
+# PORTME Fill in your ld.so characteristics
+echo $ac_n "checking dynamic linker characteristics""... $ac_c" 1>&6
+echo "configure:3849: checking dynamic linker characteristics" >&5
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so$major'
+ ;;
+
+aix4* | aix5*)
+ version_type=linux
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can
+ # not hardcode correct soname into executable. Probably we can
+ # add versioning support to collect2, so additional links can
+ # be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}.so$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}.so'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi4*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ export_dynamic_flag_spec=-rdynamic
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32*)
+ version_type=windows
+ need_version=no
+ need_lib_prefix=no
+ case $GCC,$host_os in
+ yes,cygwin*)
+ library_names_spec='$libname.dll.a'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+ postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog .libs/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $rm \$dlpath'
+ ;;
+ yes,mingw*)
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
+ ;;
+ yes,pw32*)
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/./-/g'`${versuffix}.dll'
+ ;;
+ *)
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ # FIXME: Relying on posixy $() will cause problems for
+ # cross-compilation, but unfortunately the echo tests do not
+ # yet detect zsh echo's removal of \ escapes.
+ library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)'
+ soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ *)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+ soname_spec='${libname}${release}.sl$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5* | irix6*)
+ version_type=irix
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
+ case $host_os in
+ irix5*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+openbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case "$host_os" in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ need_lib_prefix=no
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_version=no
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+ soname_spec='$libname.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$ac_t""$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# Report the final consequences.
+echo $ac_n "checking if libtool supports shared libraries""... $ac_c" 1>&6
+echo "configure:4250: checking if libtool supports shared libraries" >&5
+echo "$ac_t""$can_build_shared" 1>&6
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+echo $ac_n "checking whether to build shared libraries""... $ac_c" 1>&6
+echo "configure:4258: checking whether to build shared libraries" >&5
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+esac
+echo "$ac_t""$enable_shared" 1>&6
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+echo $ac_n "checking whether to build static libraries""... $ac_c" 1>&6
+echo "configure:4285: checking whether to build static libraries" >&5
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+echo "$ac_t""$enable_static" 1>&6
+##
+## END FIXME
+
+if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ *)
+ echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "configure:4328: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4333 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shl_load(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4356: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "configure:4374: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4382 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo configure:4393: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "configure:4412: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4417 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlopen(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4440: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:4458: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4466 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:4477: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen in -lsvld""... $ac_c" 1>&6
+echo "configure:4496: checking for dlopen in -lsvld" >&5
+ac_lib_var=`echo svld'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsvld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4504 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:4515: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "configure:4534: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4542 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo configure:4553: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "configure:4609: checking whether a program can dlopen itself" >&5
+if eval "test \"`echo '$''{'lt_cv_dlopen_self'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+#line 4619 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+
+ exit (status);
+}
+EOF
+ if { (eval echo configure:4680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ LDFLAGS="$LDFLAGS $link_static_flag"
+ echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "configure:4703: checking whether a statically linked program can dlopen itself" >&5
+if eval "test \"`echo '$''{'lt_cv_dlopen_self_static'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+#line 4713 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+
+ exit (status);
+}
+EOF
+ if { (eval echo configure:4774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+## FIXME: this should be a separate macro
+##
+if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ echo $ac_n "checking whether -lc should be explicitly linked in""... $ac_c" 1>&6
+echo "configure:4825: checking whether -lc should be explicitly linked in" >&5
+ if eval "test \"`echo '$''{'lt_cv_archive_cmds_need_lc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ $rm conftest*
+ echo 'static int dummy;' > conftest.$ac_ext
+
+ if { (eval echo configure:4832: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_cv_prog_cc_wl
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { (eval echo configure:4845: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\") 1>&5; (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+fi
+
+ echo "$ac_t""$lt_cv_archive_cmds_need_lc" 1>&6
+ ;;
+ esac
+fi
+need_lc=${lt_cv_archive_cmds_need_lc-yes}
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# The second clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+ :
+else
+ # If there is no Makefile yet, we rely on a make rule to execute
+ # `config.status --recheck' to rerun these tests and create the
+ # libtool script then.
+ test -f Makefile && make "$ltmain"
+fi
+
+if test -f "$ltmain"; then
+ trap "$rm \"${ofile}T\"; exit 1" 1 2 15
+ $rm -f "${ofile}T"
+
+ echo creating $ofile
+
+ # Now quote all the things that may contain metacharacters while being
+ # careful not to overquote the AC_SUBSTed values. We take copies of the
+ # variables and quote the copies for generation of the libtool script.
+ for var in echo old_CC old_CFLAGS \
+ AR AR_FLAGS CC LD LN_S NM SHELL \
+ reload_flag reload_cmds wl \
+ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+ library_names_spec soname_spec \
+ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \
+ postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \
+ old_striplib striplib file_magic_cmd export_symbols_cmds \
+ deplibs_check_method allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+ global_symbol_to_c_name_address \
+ hardcode_libdir_flag_spec hardcode_libdir_separator \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+ case $var in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+ extract_expsyms_cmds | old_archive_from_expsyms_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ cat <<__EOF__ > "${ofile}T"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996-2000 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$need_lc
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# The default C compiler.
+CC=$lt_CC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_pic_flag
+pic_mode=$pic_mode
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$lt_compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+ case $host_os in
+ aix3*)
+ cat <<\EOF >> "${ofile}T"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2*)
+ cat <<'EOF' >> "${ofile}T"
+ # This is a source program that is used to create dlls on Windows
+ # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+ # This is a source program that is used to create import libraries
+ # on Windows for dlls which lack them. Don't remove nor modify the
+ # starting and closing comments
+# /* impgen.c starts here */
+# /* Copyright (C) 1999-2000 Free Software Foundation, Inc.
+#
+# This file is part of GNU libtool.
+#
+# 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# */
+#
+# #include <stdio.h> /* for printf() */
+# #include <unistd.h> /* for open(), lseek(), read() */
+# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
+# #include <string.h> /* for strdup() */
+#
+# /* O_BINARY isn't required (or even defined sometimes) under Unix */
+# #ifndef O_BINARY
+# #define O_BINARY 0
+# #endif
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[2];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 2);
+# return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[4];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 4);
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+# void *ptr;
+# {
+# unsigned char *b = ptr;
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+# int argc;
+# char *argv[];
+# {
+# int dll;
+# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+# unsigned long export_rva, export_size, nsections, secptr, expptr;
+# unsigned long name_rvas, nexp;
+# unsigned char *expdata, *erva;
+# char *filename, *dll_name;
+#
+# filename = argv[1];
+#
+# dll = open(filename, O_RDONLY|O_BINARY);
+# if (dll < 1)
+# return 1;
+#
+# dll_name = filename;
+#
+# for (i=0; filename[i]; i++)
+# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+# dll_name = filename + i +1;
+#
+# pe_header_offset = pe_get32 (dll, 0x3c);
+# opthdr_ofs = pe_header_offset + 4 + 20;
+# num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+# if (num_entries < 1) /* no exports */
+# return 1;
+#
+# export_rva = pe_get32 (dll, opthdr_ofs + 96);
+# export_size = pe_get32 (dll, opthdr_ofs + 100);
+# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+# secptr = (pe_header_offset + 4 + 20 +
+# pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+# expptr = 0;
+# for (i = 0; i < nsections; i++)
+# {
+# char sname[8];
+# unsigned long secptr1 = secptr + 40 * i;
+# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# lseek(dll, secptr1, SEEK_SET);
+# read(dll, sname, 8);
+# if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# {
+# expptr = fptr + (export_rva - vaddr);
+# if (export_rva + export_size > vaddr + vsize)
+# export_size = vsize - (export_rva - vaddr);
+# break;
+# }
+# }
+#
+# expdata = (unsigned char*)malloc(export_size);
+# lseek (dll, expptr, SEEK_SET);
+# read (dll, expdata, export_size);
+# erva = expdata - export_rva;
+#
+# nexp = pe_as32 (expdata+24);
+# name_rvas = pe_as32 (expdata+32);
+#
+# printf ("EXPORTS\n");
+# for (i = 0; i<nexp; i++)
+# {
+# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+# }
+#
+# return 0;
+# }
+# /* impgen.c ends here */
+
+EOF
+ ;;
+ esac
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1)
+
+ mv -f "${ofile}T" "$ofile" || \
+ (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
+ chmod +x "$ofile"
+fi
+##
+## END FIXME
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Prevent multiple expansion
+
+
+ EXTLIB='la'
+ EXTOBJ='lo'
+ LIBTOOL='$(top)/libtool'
+ LIBTOOLCC='$(top)/libtool --mode=compile'
+ LIBTOOLLD='$(top)/libtool --mode=link'
+ CCOUTPUT='-c -o $@ $<'
+else
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:5446: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+ EXTLIB='a'
+ EXTOBJ='o'
+ LIBTOOL=''
+ LIBTOOLCC=''
+ LIBTOOLLD=''
+ if test x"$compiler_c_o" = xyes ; then
+ CCOUTPUT='-c -o $@ $<'
+ else
+ CCOUTPUT='-c $< && if test x"$(@F)" != x"$@" ; then mv $(@F) $@ ; fi'
+ fi
+
+fi
+
+
+
+
+
+
+
+
+# Check whether --with-control-dir or --without-control-dir was given.
+if test "${with_control_dir+set}" = set; then
+ withval="$with_control_dir"
+ CONTROLDIR=$with_control_dir
+else
+ CONTROLDIR=$prefix/bin/control
+fi
+
+
+# Check whether --with-db-dir or --without-db-dir was given.
+if test "${with_db_dir+set}" = set; then
+ withval="$with_db_dir"
+ DBDIR=$with_db_dir
+else
+ DBDIR=$prefix/db
+fi
+
+
+# Check whether --with-doc-dir or --without-doc-dir was given.
+if test "${with_doc_dir+set}" = set; then
+ withval="$with_doc_dir"
+ DOCDIR=$with_doc_dir
+else
+ DOCDIR=$prefix/doc
+fi
+
+
+# Check whether --with-etc-dir or --without-etc-dir was given.
+if test "${with_etc_dir+set}" = set; then
+ withval="$with_etc_dir"
+ ETCDIR=$with_etc_dir
+else
+ ETCDIR=$prefix/etc
+fi
+
+
+# Check whether --with-filter-dir or --without-filter-dir was given.
+if test "${with_filter_dir+set}" = set; then
+ withval="$with_filter_dir"
+ FILTERDIR=$with_filter_dir
+else
+ FILTERDIR=$prefix/bin/filter
+fi
+
+
+# Check whether --with-lib-dir or --without-lib-dir was given.
+if test "${with_lib_dir+set}" = set; then
+ withval="$with_lib_dir"
+ LIBDIR=$with_lib_dir
+else
+ LIBDIR=$prefix/lib
+fi
+
+
+# Check whether --with-log-dir or --without-log-dir was given.
+if test "${with_log_dir+set}" = set; then
+ withval="$with_log_dir"
+ LOGDIR=$with_log_dir
+else
+ LOGDIR=$prefix/log
+fi
+
+
+# Check whether --with-run-dir or --without-run-dir was given.
+if test "${with_run_dir+set}" = set; then
+ withval="$with_run_dir"
+ RUNDIR=$with_run_dir
+else
+ RUNDIR=$prefix/run
+fi
+
+
+# Check whether --with-spool-dir or --without-spool-dir was given.
+if test "${with_spool_dir+set}" = set; then
+ withval="$with_spool_dir"
+ SPOOLDIR=$with_spool_dir
+else
+ SPOOLDIR=$prefix/spool
+fi
+
+
+# Check whether --with-tmp-dir or --without-tmp-dir was given.
+if test "${with_tmp_dir+set}" = set; then
+ withval="$with_tmp_dir"
+ tmpdir=$with_tmp_dir
+else
+ tmpdir=$prefix/tmp
+fi
+
+
+
+# Check whether --with-syslog-facility or --without-syslog-facility was given.
+if test "${with_syslog_facility+set}" = set; then
+ withval="$with_syslog_facility"
+ SYSLOG_FACILITY=$with_syslog_facility
+else
+ SYSLOG_FACILITY=none
+fi
+
+
+
+
+# Check whether --with-news-user or --without-news-user was given.
+if test "${with_news_user+set}" = set; then
+ withval="$with_news_user"
+ NEWSUSER=$with_news_user
+else
+ NEWSUSER=news
+fi
+
+
+cat >> confdefs.h <<EOF
+#define NEWSUSER "$NEWSUSER"
+EOF
+
+# Check whether --with-news-group or --without-news-group was given.
+if test "${with_news_group+set}" = set; then
+ withval="$with_news_group"
+ NEWSGRP=$with_news_group
+else
+ NEWSGRP=news
+fi
+
+
+cat >> confdefs.h <<EOF
+#define NEWSGRP "$NEWSGRP"
+EOF
+
+# Check whether --with-news-master or --without-news-master was given.
+if test "${with_news_master+set}" = set; then
+ withval="$with_news_master"
+ NEWSMASTER=$with_news_master
+else
+ NEWSMASTER=usenet
+fi
+
+
+cat >> confdefs.h <<EOF
+#define NEWSMASTER "$NEWSMASTER"
+EOF
+
+
+NEWSUMASK=02
+FILEMODE=0664
+DIRMODE=0775
+RUNDIRMODE=0770
+# Check whether --with-news-umask or --without-news-umask was given.
+if test "${with_news_umask+set}" = set; then
+ withval="$with_news_umask"
+ with_news_umask=`echo "$with_news_umask" | sed 's/^0*//'`
+ if test "x$with_news_umask" = x22 ; then
+ NEWSUMASK=022
+ FILEMODE=0644
+ DIRMODE=0755
+ RUNDIRMODE=0750
+ else
+ if test "x$with_news_umask" != x2 ; then
+ { echo "configure: error: Valid umasks are 02 or 022" 1>&2; exit 1; }
+ fi
+ fi
+fi
+
+
+
+
+
+cat >> confdefs.h <<EOF
+#define ARTFILE_MODE $FILEMODE
+EOF
+
+cat >> confdefs.h <<EOF
+#define BATCHFILE_MODE $FILEMODE
+EOF
+
+cat >> confdefs.h <<EOF
+#define GROUPDIR_MODE $DIRMODE
+EOF
+
+cat >> confdefs.h <<EOF
+#define NEWSUMASK $NEWSUMASK
+EOF
+
+
+INEWSMODE=0550
+# Check whether --enable-setgid-inews or --disable-setgid-inews was given.
+if test "${enable_setgid_inews+set}" = set; then
+ enableval="$enable_setgid_inews"
+ if test "x$enableval" = xyes ; then
+ INEWSMODE=02555
+ fi
+fi
+
+
+
+RNEWSGRP=$NEWSGRP
+RNEWSMODE=0500
+# Check whether --enable-uucp-rnews or --disable-uucp-rnews was given.
+if test "${enable_uucp_rnews+set}" = set; then
+ enableval="$enable_uucp_rnews"
+ if test "x$enableval" = xyes ; then
+ RNEWSGRP=uucp
+ RNEWSMODE=04550
+ fi
+fi
+
+
+
+
+# Check whether --with-log-compress or --without-log-compress was given.
+if test "${with_log_compress+set}" = set; then
+ withval="$with_log_compress"
+ LOG_COMPRESS=$with_log_compress
+else
+ LOG_COMPRESS=gzip
+fi
+
+case "$LOG_COMPRESS" in
+bzip2) LOG_COMPRESSEXT=".bz2" ;;
+gzip) LOG_COMPRESSEXT=".gz" ;;
+*) LOG_COMPRESSEXT=".Z" ;;
+esac
+
+
+
+# Check whether --with-innd-port or --without-innd-port was given.
+if test "${with_innd_port+set}" = set; then
+ withval="$with_innd_port"
+ cat >> confdefs.h <<EOF
+#define INND_PORT $with_innd_port
+EOF
+
+fi
+
+
+# Check whether --enable-ipv6 or --disable-ipv6 was given.
+if test "${enable_ipv6+set}" = set; then
+ enableval="$enable_ipv6"
+ if test "x$enableval" = xyes ; then
+ inn_enable_ipv6_tests=yes
+ cat >> confdefs.h <<\EOF
+#define HAVE_INET6 1
+EOF
+
+ fi
+fi
+
+
+# Check whether --with-max-sockets or --without-max-sockets was given.
+if test "${with_max_sockets+set}" = set; then
+ withval="$with_max_sockets"
+ :
+else
+ with_max_sockets=15
+fi
+
+cat >> confdefs.h <<EOF
+#define MAX_SOCKETS $with_max_sockets
+EOF
+
+
+# Check whether --enable-tagged-hash or --disable-tagged-hash was given.
+if test "${enable_tagged_hash+set}" = set; then
+ enableval="$enable_tagged_hash"
+ if test "x$enableval" = xyes ; then
+ DO_DBZ_TAGGED_HASH=DO
+ cat >> confdefs.h <<\EOF
+#define DO_TAGGED_HASH 1
+EOF
+
+ else
+ DO_DBZ_TAGGED_HASH=DONT
+ fi
+fi
+
+
+
+inn_enable_keywords=0
+# Check whether --enable-keywords or --disable-keywords was given.
+if test "${enable_keywords+set}" = set; then
+ enableval="$enable_keywords"
+ if test x"$enableval" = xyes ; then
+ inn_enable_keywords=1
+ fi
+fi
+
+cat >> confdefs.h <<EOF
+#define DO_KEYWORDS $inn_enable_keywords
+EOF
+
+
+# Check whether --enable-largefiles or --disable-largefiles was given.
+if test "${enable_largefiles+set}" = set; then
+ enableval="$enable_largefiles"
+ case "${enableval}" in
+ yes) inn_enable_largefiles=yes
+ if test x"$DO_DBZ_TAGGED_HASH" = xDO ; then
+{ echo "configure: error: --enable-tagged-hash conflicts with --enable-largefiles." 1>&2; exit 1; }
+ fi ;;
+ no) inn_enable_largefiles=no ;;
+ *) { echo "configure: error: invalid argument to --enable-largefiles" 1>&2; exit 1; } ;;
+ esac
+fi
+
+
+# Check whether --with-sendmail or --without-sendmail was given.
+if test "${with_sendmail+set}" = set; then
+ withval="$with_sendmail"
+ SENDMAIL=$with_sendmail
+fi
+
+
+# Check whether --with-kerberos or --without-kerberos was given.
+if test "${with_kerberos+set}" = set; then
+ withval="$with_kerberos"
+ if test x"$with_kerberos" != xno ; then
+ KRB5_LDFLAGS="-L$with_kerberos/lib"
+ KRB5_INC="-I$with_kerberos/include"
+ fi
+fi
+
+
+# Check whether --with-perl or --without-perl was given.
+if test "${with_perl+set}" = set; then
+ withval="$with_perl"
+ case "${withval}" in
+ yes) DO_PERL=DO
+ cat >> confdefs.h <<\EOF
+#define DO_PERL 1
+EOF
+
+ ;;
+ no) DO_PERL=DONT ;;
+ *) { echo "configure: error: invalid argument to --with-perl" 1>&2; exit 1; } ;;
+ esac
+else
+ DO_PERL=DONT
+fi
+
+
+# Check whether --with-python or --without-python was given.
+if test "${with_python+set}" = set; then
+ withval="$with_python"
+ case "${withval}" in
+ yes) DO_PYTHON=define
+ cat >> confdefs.h <<\EOF
+#define DO_PYTHON 1
+EOF
+
+ ;;
+ no) DO_PYTHON=DONT ;;
+ *) { echo "configure: error: invalid argument to --with-python" 1>&2; exit 1; } ;;
+ esac
+else
+ DO_PYTHON=DONT
+fi
+
+
+HOSTNAME=`hostname 2> /dev/null || uname -n`
+
+
+if test $ac_cv_prog_gcc = yes; then
+ echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:5848: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat > conftest.$ac_ext <<EOF
+#line 5854 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+else
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat > conftest.$ac_ext <<EOF
+#line 5872 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5896: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="flex"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+ case "$LEX" in
+ flex*) ac_lib=fl ;;
+ *) ac_lib=l ;;
+ esac
+ echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:5930: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5938 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap();
+
+int main() {
+yywrap()
+; return 0; }
+EOF
+if { (eval echo configure:5949: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LEXLIB="-l$ac_lib"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:5972: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6001: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6033: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+
+case "$CPP" in
+*-traditional-cpp*)
+ CFLAGS="-traditional-cpp $CFLAGS"
+ ;;
+esac
+
+case "$host" in
+
+*hpux*)
+ if test x"$GCC" != xyes ; then
+ CFLAGS="$CFLAGS -Ae"
+
+ case "$CFLAGS" in
+ *-g*)
+ LDFLAGS="$LDFLAGS -g"
+ ;;
+ esac
+ fi
+ ;;
+
+*darwin*)
+ LDFLAGS="$LDFLAGS -multiply_defined suppress"
+ ;;
+
+*UnixWare*|*unixware*|*-sco3*)
+ if test x"$GCC" != xyes ; then
+ CFLAGS="$CFLAGS -Kalloca"
+ fi
+esac
+
+
+# Extract the first word of "ctags", so it can be a program name with args.
+set dummy ctags; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6098: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_CTAGS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$CTAGS" in
+ /*)
+ ac_cv_path_CTAGS="$CTAGS" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_CTAGS="$CTAGS" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_CTAGS="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_CTAGS" && ac_cv_path_CTAGS="echo"
+ ;;
+esac
+fi
+CTAGS="$ac_cv_path_CTAGS"
+if test -n "$CTAGS"; then
+ echo "$ac_t""$CTAGS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test x"$CTAGS" != xecho ; then
+ CTAGS="$CTAGS -t -w"
+fi
+
+
+
+# Extract the first word of "awk", so it can be a program name with args.
+set dummy awk; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6140: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path__PATH_AWK'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$_PATH_AWK" in
+ /*)
+ ac_cv_path__PATH_AWK="$_PATH_AWK" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path__PATH_AWK="$_PATH_AWK" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path__PATH_AWK="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+_PATH_AWK="$ac_cv_path__PATH_AWK"
+if test -n "$_PATH_AWK"; then
+ echo "$ac_t""$_PATH_AWK" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "${_PATH_AWK}" ; then
+ { echo "configure: error: awk was not found in path and is required" 1>&2; exit 1; }
+fi
+# Extract the first word of "egrep", so it can be a program name with args.
+set dummy egrep; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6178: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path__PATH_EGREP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$_PATH_EGREP" in
+ /*)
+ ac_cv_path__PATH_EGREP="$_PATH_EGREP" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path__PATH_EGREP="$_PATH_EGREP" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path__PATH_EGREP="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+_PATH_EGREP="$ac_cv_path__PATH_EGREP"
+if test -n "$_PATH_EGREP"; then
+ echo "$ac_t""$_PATH_EGREP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "${_PATH_EGREP}" ; then
+ { echo "configure: error: egrep was not found in path and is required" 1>&2; exit 1; }
+fi
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6216: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path__PATH_PERL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$_PATH_PERL" in
+ /*)
+ ac_cv_path__PATH_PERL="$_PATH_PERL" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path__PATH_PERL="$_PATH_PERL" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path__PATH_PERL="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+_PATH_PERL="$ac_cv_path__PATH_PERL"
+if test -n "$_PATH_PERL"; then
+ echo "$ac_t""$_PATH_PERL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "${_PATH_PERL}" ; then
+ { echo "configure: error: perl was not found in path and is required" 1>&2; exit 1; }
+fi
+# Extract the first word of "sh", so it can be a program name with args.
+set dummy sh; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6254: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path__PATH_SH'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$_PATH_SH" in
+ /*)
+ ac_cv_path__PATH_SH="$_PATH_SH" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path__PATH_SH="$_PATH_SH" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path__PATH_SH="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+_PATH_SH="$ac_cv_path__PATH_SH"
+if test -n "$_PATH_SH"; then
+ echo "$ac_t""$_PATH_SH" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "${_PATH_SH}" ; then
+ { echo "configure: error: sh was not found in path and is required" 1>&2; exit 1; }
+fi
+# Extract the first word of "sed", so it can be a program name with args.
+set dummy sed; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6292: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path__PATH_SED'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$_PATH_SED" in
+ /*)
+ ac_cv_path__PATH_SED="$_PATH_SED" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path__PATH_SED="$_PATH_SED" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path__PATH_SED="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+_PATH_SED="$ac_cv_path__PATH_SED"
+if test -n "$_PATH_SED"; then
+ echo "$ac_t""$_PATH_SED" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "${_PATH_SED}" ; then
+ { echo "configure: error: sed was not found in path and is required" 1>&2; exit 1; }
+fi
+# Extract the first word of "sort", so it can be a program name with args.
+set dummy sort; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6330: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path__PATH_SORT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$_PATH_SORT" in
+ /*)
+ ac_cv_path__PATH_SORT="$_PATH_SORT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path__PATH_SORT="$_PATH_SORT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path__PATH_SORT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+_PATH_SORT="$ac_cv_path__PATH_SORT"
+if test -n "$_PATH_SORT"; then
+ echo "$ac_t""$_PATH_SORT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "${_PATH_SORT}" ; then
+ { echo "configure: error: sort was not found in path and is required" 1>&2; exit 1; }
+fi
+for ac_prog in uux
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6370: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path__PATH_UUX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$_PATH_UUX" in
+ /*)
+ ac_cv_path__PATH_UUX="$_PATH_UUX" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path__PATH_UUX="$_PATH_UUX" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path__PATH_UUX="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+_PATH_UUX="$ac_cv_path__PATH_UUX"
+if test -n "$_PATH_UUX"; then
+ echo "$ac_t""$_PATH_UUX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$_PATH_UUX" && break
+done
+test -n "$_PATH_UUX" || _PATH_UUX="uux"
+
+
+inn_perl_command='print $]'
+
+
+echo $ac_n "checking for Perl version""... $ac_c" 1>&6
+echo "configure:6411: checking for Perl version" >&5
+if eval "test \"`echo '$''{'inn_cv_perl_version'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if $_PATH_PERL -e 'require 5.004_03;' > /dev/null 2>&1 ; then
+ inn_cv_perl_version=`$_PATH_PERL -e "$inn_perl_command"`
+else
+ { echo "configure: error: Perl 5.004_03 or greater is required" 1>&2; exit 1; }
+fi
+fi
+
+echo "$ac_t""$inn_cv_perl_version" 1>&6
+
+pgpverify=true
+for ac_prog in gpgv
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6430: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_PATH_GPGV'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$PATH_GPGV" in
+ /*)
+ ac_cv_path_PATH_GPGV="$PATH_GPGV" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_PATH_GPGV="$PATH_GPGV" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_PATH_GPGV="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+PATH_GPGV="$ac_cv_path_PATH_GPGV"
+if test -n "$PATH_GPGV"; then
+ echo "$ac_t""$PATH_GPGV" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$PATH_GPGV" && break
+done
+
+for ac_prog in pgpv pgp pgpgpg
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6470: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path__PATH_PGP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$_PATH_PGP" in
+ /*)
+ ac_cv_path__PATH_PGP="$_PATH_PGP" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path__PATH_PGP="$_PATH_PGP" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path__PATH_PGP="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+_PATH_PGP="$ac_cv_path__PATH_PGP"
+if test -n "$_PATH_PGP"; then
+ echo "$ac_t""$_PATH_PGP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$_PATH_PGP" && break
+done
+
+if test -z "$_PATH_PGP" && test -z "$PATH_GPGV" ; then
+ pgpverify=false
+fi
+
+
+for ac_prog in wget ncftpget ncftp
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6515: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GETFTP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GETFTP" in
+ /*)
+ ac_cv_path_GETFTP="$GETFTP" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GETFTP="$GETFTP" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GETFTP="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+GETFTP="$ac_cv_path_GETFTP"
+if test -n "$GETFTP"; then
+ echo "$ac_t""$GETFTP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$GETFTP" && break
+done
+test -n "$GETFTP" || GETFTP="$prefix/bin/simpleftp"
+
+
+case "$LOG_COMPRESS" in
+compress|gzip) ;;
+*) # Extract the first word of ""$LOG_COMPRESS"", so it can be a program name with args.
+set dummy "$LOG_COMPRESS"; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6557: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_LOG_COMPRESS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$LOG_COMPRESS" in
+ /*)
+ ac_cv_path_LOG_COMPRESS="$LOG_COMPRESS" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_LOG_COMPRESS="$LOG_COMPRESS" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_LOG_COMPRESS="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+LOG_COMPRESS="$ac_cv_path_LOG_COMPRESS"
+if test -n "$LOG_COMPRESS"; then
+ echo "$ac_t""$LOG_COMPRESS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "${LOG_COMPRESS}" ; then
+ { echo "configure: error: "$LOG_COMPRESS" was not found in path and is required" 1>&2; exit 1; }
+fi
+esac
+# Extract the first word of "compress", so it can be a program name with args.
+set dummy compress; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6596: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_COMPRESS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$COMPRESS" in
+ /*)
+ ac_cv_path_COMPRESS="$COMPRESS" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_COMPRESS="$COMPRESS" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_COMPRESS="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_COMPRESS" && ac_cv_path_COMPRESS="compress"
+ ;;
+esac
+fi
+COMPRESS="$ac_cv_path_COMPRESS"
+if test -n "$COMPRESS"; then
+ echo "$ac_t""$COMPRESS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test x"$LOG_COMPRESS" = xcompress ; then
+ if test x"$COMPRESS" = xcompress ; then
+ { echo "configure: error: compress not found but specified for log compression" 1>&2; exit 1; }
+ fi
+ LOG_COMPRESS="$COMPRESS"
+fi
+# Extract the first word of "gzip", so it can be a program name with args.
+set dummy gzip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6638: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GZIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GZIP" in
+ /*)
+ ac_cv_path_GZIP="$GZIP" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GZIP="$GZIP" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GZIP="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GZIP" && ac_cv_path_GZIP="gzip"
+ ;;
+esac
+fi
+GZIP="$ac_cv_path_GZIP"
+if test -n "$GZIP"; then
+ echo "$ac_t""$GZIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test x"$LOG_COMPRESS" = xgzip ; then
+ if test x"$GZIP" = xgzip ; then
+ { echo "configure: error: gzip not found but specified for log compression" 1>&2; exit 1; }
+ fi
+ LOG_COMPRESS="$GZIP"
+fi
+
+if test x"$COMPRESS" = xcompress && test x"$GZIP" != xgzip ; then
+ UNCOMPRESS="$GZIP -d"
+else
+ UNCOMPRESS="$COMPRESS -d"
+fi
+
+
+if test "${with_sendmail+set}" = set ; then
+ echo $ac_n "checking for sendmail""... $ac_c" 1>&6
+echo "configure:6687: checking for sendmail" >&5
+ echo "$ac_t""$SENDMAIL" 1>&6
+else
+ # Extract the first word of "sendmail", so it can be a program name with args.
+set dummy sendmail; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6693: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_SENDMAIL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$SENDMAIL" in
+ /*)
+ ac_cv_path_SENDMAIL="$SENDMAIL" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_SENDMAIL="$SENDMAIL" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy=""/usr/sbin:/usr/lib""
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_SENDMAIL="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+SENDMAIL="$ac_cv_path_SENDMAIL"
+if test -n "$SENDMAIL"; then
+ echo "$ac_t""$SENDMAIL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$SENDMAIL" ; then
+ { echo "configure: error: sendmail not found" 1>&2; exit 1; }
+ fi
+fi
+
+# Extract the first word of "uustat", so it can be a program name with args.
+set dummy uustat; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6733: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_HAVE_UUSTAT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$HAVE_UUSTAT"; then
+ ac_cv_prog_HAVE_UUSTAT="$HAVE_UUSTAT" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_HAVE_UUSTAT="DO"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_HAVE_UUSTAT" && ac_cv_prog_HAVE_UUSTAT="DONT"
+fi
+fi
+HAVE_UUSTAT="$ac_cv_prog_HAVE_UUSTAT"
+if test -n "$HAVE_UUSTAT"; then
+ echo "$ac_t""$HAVE_UUSTAT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+if test x"$DO_PYTHON" = xdefine ; then
+ # Extract the first word of "python", so it can be a program name with args.
+set dummy python; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6766: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path__PATH_PYTHON'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$_PATH_PYTHON" in
+ /*)
+ ac_cv_path__PATH_PYTHON="$_PATH_PYTHON" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path__PATH_PYTHON="$_PATH_PYTHON" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path__PATH_PYTHON="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+_PATH_PYTHON="$ac_cv_path__PATH_PYTHON"
+if test -n "$_PATH_PYTHON"; then
+ echo "$ac_t""$_PATH_PYTHON" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "${_PATH_PYTHON}" ; then
+ { echo "configure: error: python was not found in path and is required" 1>&2; exit 1; }
+fi
+fi
+
+
+
+
+
+echo $ac_n "checking for library containing setproctitle""... $ac_c" 1>&6
+echo "configure:6808: checking for library containing setproctitle" >&5
+if eval "test \"`echo '$''{'ac_cv_search_setproctitle'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_setproctitle="no"
+cat > conftest.$ac_ext <<EOF
+#line 6815 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char setproctitle();
+
+int main() {
+setproctitle()
+; return 0; }
+EOF
+if { (eval echo configure:6826: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_setproctitle="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_setproctitle" = "no" && for i in util; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6837 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char setproctitle();
+
+int main() {
+setproctitle()
+; return 0; }
+EOF
+if { (eval echo configure:6848: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_setproctitle="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_setproctitle" 1>&6
+if test "$ac_cv_search_setproctitle" != "no"; then
+ test "$ac_cv_search_setproctitle" = "none required" || LIBS="$ac_cv_search_setproctitle $LIBS"
+ cat >> confdefs.h <<\EOF
+#define HAVE_SETPROCTITLE 1
+EOF
+
+else :
+ LIBOBJS="$LIBOBJS setproctitle.o"
+ for ac_func in pstat
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:6873: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6878 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6901: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+
+echo $ac_n "checking for library containing gethostbyname""... $ac_c" 1>&6
+echo "configure:6929: checking for library containing gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_search_gethostbyname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_gethostbyname="no"
+cat > conftest.$ac_ext <<EOF
+#line 6936 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:6947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_gethostbyname="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_gethostbyname" = "no" && for i in nsl; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6958 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:6969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_gethostbyname="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_gethostbyname" 1>&6
+if test "$ac_cv_search_gethostbyname" != "no"; then
+ test "$ac_cv_search_gethostbyname" = "none required" || LIBS="$ac_cv_search_gethostbyname $LIBS"
+
+else :
+
+fi
+
+echo $ac_n "checking for library containing socket""... $ac_c" 1>&6
+echo "configure:6991: checking for library containing socket" >&5
+if eval "test \"`echo '$''{'ac_cv_search_socket'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_socket="no"
+cat > conftest.$ac_ext <<EOF
+#line 6998 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:7009: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_socket="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_socket" = "no" && for i in socket; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7020 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:7031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_socket="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_socket" 1>&6
+if test "$ac_cv_search_socket" != "no"; then
+ test "$ac_cv_search_socket" = "none required" || LIBS="$ac_cv_search_socket $LIBS"
+
+else :
+ echo $ac_n "checking for socket in -lnsl""... $ac_c" 1>&6
+echo "configure:7050: checking for socket in -lnsl" >&5
+ac_lib_var=`echo nsl'_'socket | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lnsl -lsocket $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7058 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:7069: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lsocket -lnsl"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+echo $ac_n "checking for library containing inet_aton""... $ac_c" 1>&6
+echo "configure:7093: checking for library containing inet_aton" >&5
+if eval "test \"`echo '$''{'ac_cv_search_inet_aton'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_inet_aton="no"
+cat > conftest.$ac_ext <<EOF
+#line 7100 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char inet_aton();
+
+int main() {
+inet_aton()
+; return 0; }
+EOF
+if { (eval echo configure:7111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_inet_aton="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_inet_aton" = "no" && for i in resolv; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7122 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char inet_aton();
+
+int main() {
+inet_aton()
+; return 0; }
+EOF
+if { (eval echo configure:7133: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_inet_aton="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_inet_aton" 1>&6
+if test "$ac_cv_search_inet_aton" != "no"; then
+ test "$ac_cv_search_inet_aton" = "none required" || LIBS="$ac_cv_search_inet_aton $LIBS"
+
+else :
+
+fi
+
+inn_save_LIBS=$LIBS
+LIBS=${CRYPT_LIB}
+
+echo $ac_n "checking for library containing crypt""... $ac_c" 1>&6
+echo "configure:7158: checking for library containing crypt" >&5
+if eval "test \"`echo '$''{'ac_cv_search_crypt'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_crypt="no"
+cat > conftest.$ac_ext <<EOF
+#line 7165 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char crypt();
+
+int main() {
+crypt()
+; return 0; }
+EOF
+if { (eval echo configure:7176: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_crypt="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_crypt" = "no" && for i in crypt; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7187 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char crypt();
+
+int main() {
+crypt()
+; return 0; }
+EOF
+if { (eval echo configure:7198: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_crypt="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_crypt" 1>&6
+if test "$ac_cv_search_crypt" != "no"; then
+ test "$ac_cv_search_crypt" = "none required" || LIBS="$ac_cv_search_crypt $LIBS"
+ CRYPT_LIB=$LIBS
+
+else :
+
+fi
+LIBS=$inn_save_LIBS
+
+inn_save_LIBS=$LIBS
+LIBS=${SHADOW_LIB}
+
+echo $ac_n "checking for library containing getspnam""... $ac_c" 1>&6
+echo "configure:7225: checking for library containing getspnam" >&5
+if eval "test \"`echo '$''{'ac_cv_search_getspnam'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_getspnam="no"
+cat > conftest.$ac_ext <<EOF
+#line 7232 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getspnam();
+
+int main() {
+getspnam()
+; return 0; }
+EOF
+if { (eval echo configure:7243: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_getspnam="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_getspnam" = "no" && for i in shadow; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7254 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getspnam();
+
+int main() {
+getspnam()
+; return 0; }
+EOF
+if { (eval echo configure:7265: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_getspnam="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_getspnam" 1>&6
+if test "$ac_cv_search_getspnam" != "no"; then
+ test "$ac_cv_search_getspnam" = "none required" || LIBS="$ac_cv_search_getspnam $LIBS"
+ SHADOW_LIB=$LIBS
+
+else :
+
+fi
+LIBS=$inn_save_LIBS
+
+
+inn_check_pam=1
+for ac_hdr in pam/pam_appl.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:7294: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7299 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:7304: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+ac_safe=`echo "security/pam_appl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for security/pam_appl.h""... $ac_c" 1>&6
+echo "configure:7329: checking for security/pam_appl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 7334 "configure"
+#include "confdefs.h"
+#include <security/pam_appl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:7339: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+inn_check_pam=0
+fi
+
+fi
+done
+
+if test x"$inn_check_pam" = x1; then
+ inn_save_LIBS=$LIBS
+LIBS=${PAM_LIB}
+
+echo $ac_n "checking for library containing pam_start""... $ac_c" 1>&6
+echo "configure:7369: checking for library containing pam_start" >&5
+if eval "test \"`echo '$''{'ac_cv_search_pam_start'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_pam_start="no"
+cat > conftest.$ac_ext <<EOF
+#line 7376 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char pam_start();
+
+int main() {
+pam_start()
+; return 0; }
+EOF
+if { (eval echo configure:7387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_pam_start="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_pam_start" = "no" && for i in pam; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7398 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char pam_start();
+
+int main() {
+pam_start()
+; return 0; }
+EOF
+if { (eval echo configure:7409: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_pam_start="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_pam_start" 1>&6
+if test "$ac_cv_search_pam_start" != "no"; then
+ test "$ac_cv_search_pam_start" = "none required" || LIBS="$ac_cv_search_pam_start $LIBS"
+ PAM_LIB=$LIBS
+ cat >> confdefs.h <<\EOF
+#define HAVE_PAM 1
+EOF
+
+else :
+
+fi
+LIBS=$inn_save_LIBS
+
+fi
+
+if test x"$inn_enable_keywords" = x1 ; then
+ inn_save_LIBS=$LIBS
+LIBS=${REGEX_LIB}
+
+echo $ac_n "checking for library containing regexec""... $ac_c" 1>&6
+echo "configure:7442: checking for library containing regexec" >&5
+if eval "test \"`echo '$''{'ac_cv_search_regexec'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_regexec="no"
+cat > conftest.$ac_ext <<EOF
+#line 7449 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char regexec();
+
+int main() {
+regexec()
+; return 0; }
+EOF
+if { (eval echo configure:7460: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_regexec="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_regexec" = "no" && for i in regex; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7471 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char regexec();
+
+int main() {
+regexec()
+; return 0; }
+EOF
+if { (eval echo configure:7482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_regexec="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_regexec" 1>&6
+if test "$ac_cv_search_regexec" != "no"; then
+ test "$ac_cv_search_regexec" = "none required" || LIBS="$ac_cv_search_regexec $LIBS"
+ REGEX_LIB=$LIBS
+
+else :
+ { echo "configure: error: no usable regular expression library found" 1>&2; exit 1; }
+fi
+LIBS=$inn_save_LIBS
+
+fi
+
+
+# Check whether --with-berkeleydb or --without-berkeleydb was given.
+if test "${with_berkeleydb+set}" = set; then
+ withval="$with_berkeleydb"
+ BERKELEY_DB_DIR=$with_berkeleydb
+else
+ BERKELEY_DB_DIR=no
+fi
+
+echo $ac_n "checking if BerkeleyDB is desired""... $ac_c" 1>&6
+echo "configure:7517: checking if BerkeleyDB is desired" >&5
+if test x"$BERKELEY_DB_DIR" = xno ; then
+ echo "$ac_t""no" 1>&6
+ BERKELEY_DB_LDFLAGS=
+ BERKELEY_DB_CFLAGS=
+ BERKELEY_DB_LIB=
+else
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for BerkeleyDB location""... $ac_c" 1>&6
+echo "configure:7526: checking for BerkeleyDB location" >&5
+ if test x"$BERKELEY_DB_DIR" = xyes ; then
+ for v in BerkeleyDB BerkeleyDB.3.0 BerkeleyDB.3.1 BerkeleyDB.3.2 \
+ BerkeleyDB.3.3 BerkeleyDB.4.0 BerkeleyDB.4.1 BerkeleyDB.4.2 \
+ BerkeleyDB.4.3 BerkeleyDB.4.4 BerkeleyDB.4.5 BerkeleyDB.4.6; do
+ for d in $prefix /usr/local /opt /usr ; do
+ if test -d "$d/$v" ; then
+ BERKELEY_DB_DIR="$d/$v"
+ break
+ fi
+ done
+ done
+ fi
+ if test x"$BERKELEY_DB_DIR" = xyes ; then
+ for v in db46 db45 db44 db43 db42 db41 db4 db3 db2 ; do
+ if test -d "/usr/local/include/$v" ; then
+ BERKELEY_DB_LDFLAGS="-L/usr/local/lib"
+ BERKELEY_DB_CFLAGS="-I/usr/local/include/$v"
+ BERKELEY_DB_LIB="-l$v"
+ echo "$ac_t""FreeBSD locations" 1>&6
+ break
+ fi
+ done
+ if test x"$BERKELEY_DB_LIB" = x ; then
+ for v in db44 db43 db42 db41 db4 db3 db2 ; do
+ if test -d "/usr/include/$v" ; then
+ BERKELEY_DB_CFLAGS="-I/usr/include/$v"
+ BERKELEY_DB_LIB="-l$v"
+ echo "$ac_t""Linux locations" 1>&6
+ break
+ fi
+ done
+ if test x"$BERKELEY_DB_LIB" = x ; then
+ BERKELEY_DB_LIB=-ldb
+ echo "$ac_t""trying -ldb" 1>&6
+ fi
+ fi
+ else
+ BERKELEY_DB_LDFLAGS="-L$BERKELEY_DB_DIR/lib"
+ BERKELEY_DB_CFLAGS="-I$BERKELEY_DB_DIR/include"
+ BERKELEY_DB_LIB="-ldb"
+ echo "$ac_t""$BERKELEY_DB_DIR" 1>&6
+ fi
+ cat >> confdefs.h <<\EOF
+#define USE_BERKELEY_DB 1
+EOF
+
+fi
+
+
+
+
+if test x"$BERKELEY_DB_LIB" != x ; then
+ DBM_INC="$BERKELEY_DB_CFLAGS"
+ DBM_LIB="$BERKELEY_DB_LDFLAGS $BERKELEY_DB_LIB"
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_BDB_DBM 1
+EOF
+
+else
+ inn_save_LIBS=$LIBS
+LIBS=${DBM_LIB}
+
+echo $ac_n "checking for library containing dbm_open""... $ac_c" 1>&6
+echo "configure:7591: checking for library containing dbm_open" >&5
+if eval "test \"`echo '$''{'ac_cv_search_dbm_open'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_dbm_open="no"
+cat > conftest.$ac_ext <<EOF
+#line 7598 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dbm_open();
+
+int main() {
+dbm_open()
+; return 0; }
+EOF
+if { (eval echo configure:7609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_dbm_open="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_dbm_open" = "no" && for i in ndbm dbm; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7620 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dbm_open();
+
+int main() {
+dbm_open()
+; return 0; }
+EOF
+if { (eval echo configure:7631: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_dbm_open="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_dbm_open" 1>&6
+if test "$ac_cv_search_dbm_open" != "no"; then
+ test "$ac_cv_search_dbm_open" = "none required" || LIBS="$ac_cv_search_dbm_open $LIBS"
+ DBM_LIB=$LIBS
+ cat >> confdefs.h <<\EOF
+#define HAVE_DBM 1
+EOF
+
+else :
+
+fi
+LIBS=$inn_save_LIBS
+
+ DBM_INC=
+fi
+
+
+
+# Check whether --with-openssl or --without-openssl was given.
+if test "${with_openssl+set}" = set; then
+ withval="$with_openssl"
+ OPENSSL_DIR=$with_openssl
+else
+ OPENSSL_DIR=no
+fi
+
+echo $ac_n "checking if OpenSSL is desired""... $ac_c" 1>&6
+echo "configure:7671: checking if OpenSSL is desired" >&5
+if test x"$OPENSSL_DIR" = xno ; then
+ echo "$ac_t""no" 1>&6
+ SSL_BIN=
+ SSL_INC=
+ SSL_LIB=
+else
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for OpenSSL location""... $ac_c" 1>&6
+echo "configure:7680: checking for OpenSSL location" >&5
+ if test x"$OPENSSL_DIR" = xyes ; then
+ for dir in $prefix /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg \
+ /usr/local /usr ; do
+ if test -f "$dir/include/openssl/ssl.h" ; then
+ OPENSSL_DIR=$dir
+ break
+ fi
+ done
+ fi
+ if test x"$OPENSSL_DIR" = xyes ; then
+ { echo "configure: error: Can not find OpenSSL" 1>&2; exit 1; }
+ else
+ echo "$ac_t""$OPENSSL_DIR" 1>&6
+ SSL_BIN="${OPENSSL_DIR}/bin"
+ SSL_INC="-I${OPENSSL_DIR}/include"
+
+ # This is mildly tricky. In order to satisfy most linkers, libraries
+ # have to be listed in the right order, which means that libraries
+ # with dependencies on other libraries need to be listed first. But
+ # the -L flag for the OpenSSL library directory needs to go first of
+ # all. So put the -L flag into LIBS and accumulate actual libraries
+ # into SSL_LIB, and then at the end, restore LIBS and move -L to the
+ # beginning of SSL_LIB.
+ inn_save_LIBS=$LIBS
+ LIBS="$LIBS -L${OPENSSL_DIR}/lib"
+ SSL_LIB=''
+ echo $ac_n "checking for RSAPublicEncrypt in -lrsaref""... $ac_c" 1>&6
+echo "configure:7708: checking for RSAPublicEncrypt in -lrsaref" >&5
+ac_lib_var=`echo rsaref'_'RSAPublicEncrypt | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lrsaref $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7716 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char RSAPublicEncrypt();
+
+int main() {
+RSAPublicEncrypt()
+; return 0; }
+EOF
+if { (eval echo configure:7727: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for RSAPublicEncrypt in -lRSAglue""... $ac_c" 1>&6
+echo "configure:7743: checking for RSAPublicEncrypt in -lRSAglue" >&5
+ac_lib_var=`echo RSAglue'_'RSAPublicEncrypt | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lRSAglue -lrsaref $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7751 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char RSAPublicEncrypt();
+
+int main() {
+RSAPublicEncrypt()
+; return 0; }
+EOF
+if { (eval echo configure:7762: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SSL_LIB="-lRSAglue -lrsaref"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ echo $ac_n "checking for BIO_new in -lcrypto""... $ac_c" 1>&6
+echo "configure:7787: checking for BIO_new in -lcrypto" >&5
+ac_lib_var=`echo crypto'_'BIO_new | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcrypto $SSL_LIB $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7795 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char BIO_new();
+
+int main() {
+BIO_new()
+; return 0; }
+EOF
+if { (eval echo configure:7806: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for DSO_load in -ldl""... $ac_c" 1>&6
+echo "configure:7822: checking for DSO_load in -ldl" >&5
+ac_lib_var=`echo dl'_'DSO_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl -lcrypto -ldl $SSL_LIB $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7830 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char DSO_load();
+
+int main() {
+DSO_load()
+; return 0; }
+EOF
+if { (eval echo configure:7841: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SSL_LIB="-lcrypto -ldl $SSL_LIB"
+else
+ echo "$ac_t""no" 1>&6
+SSL_LIB="-lcrypto $SSL_LIB"
+fi
+
+else
+ echo "$ac_t""no" 1>&6
+{ echo "configure: error: Can not find OpenSSL" 1>&2; exit 1; }
+fi
+
+ echo $ac_n "checking for SSL_library_init in -lssl""... $ac_c" 1>&6
+echo "configure:7868: checking for SSL_library_init in -lssl" >&5
+ac_lib_var=`echo ssl'_'SSL_library_init | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lssl $SSL_LIB $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7876 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char SSL_library_init();
+
+int main() {
+SSL_library_init()
+; return 0; }
+EOF
+if { (eval echo configure:7887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SSL_LIB="-lssl $SSL_LIB"
+else
+ echo "$ac_t""no" 1>&6
+{ echo "configure: error: Can not find OpenSSL" 1>&2; exit 1; }
+fi
+
+ SSL_LIB="-L${OPENSSL_DIR}/lib $SSL_LIB"
+ LIBS=$inn_save_LIBS
+ cat >> confdefs.h <<\EOF
+#define HAVE_SSL 1
+EOF
+
+ fi
+fi
+
+
+
+
+
+# Check whether --with-sasl or --without-sasl was given.
+if test "${with_sasl+set}" = set; then
+ withval="$with_sasl"
+ SASL_DIR=$with_sasl
+else
+ SASL_DIR=no
+fi
+
+echo $ac_n "checking if SASL is desired""... $ac_c" 1>&6
+echo "configure:7930: checking if SASL is desired" >&5
+if test x"$SASL_DIR" = xno ; then
+ echo "$ac_t""no" 1>&6
+ SASL_INC=
+ SASL_LIB=
+else
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for SASL location""... $ac_c" 1>&6
+echo "configure:7938: checking for SASL location" >&5
+ if test x"$SASL_DIR" = xyes ; then
+ for dir in $prefix /usr/local/sasl /usr/sasl /usr/pkg /usr/local ; do
+ if test -f "$dir/include/sasl/sasl.h" ; then
+ SASL_DIR=$dir
+ break
+ fi
+ done
+ fi
+ if test x"$SASL_DIR" = xyes ; then
+ if test -f "/usr/include/sasl/sasl.h" ; then
+ SASL_INC=-I/usr/include/sasl
+ SASL_DIR=/usr
+ echo "$ac_t""$SASL_DIR" 1>&6
+ inn_save_LIBS=$LIBS
+ echo $ac_n "checking for sasl_getprop in -lsasl2""... $ac_c" 1>&6
+echo "configure:7954: checking for sasl_getprop in -lsasl2" >&5
+ac_lib_var=`echo sasl2'_'sasl_getprop | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsasl2 $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7962 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char sasl_getprop();
+
+int main() {
+sasl_getprop()
+; return 0; }
+EOF
+if { (eval echo configure:7973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SASL_LIB=-lsasl2
+else
+ echo "$ac_t""no" 1>&6
+{ echo "configure: error: Can not find SASL" 1>&2; exit 1; }
+fi
+
+ LIBS=$inn_save_LIBS
+ cat >> confdefs.h <<\EOF
+#define HAVE_SASL 1
+EOF
+
+ else
+ { echo "configure: error: Can not find SASL" 1>&2; exit 1; }
+ fi
+ else
+ echo "$ac_t""$SASL_DIR" 1>&6
+ SASL_INC="-I${SASL_DIR}/include"
+
+ inn_save_LIBS=$LIBS
+ LIBS="$LIBS -L${SASL_DIR}/lib"
+ echo $ac_n "checking for sasl_getprop in -lsasl2""... $ac_c" 1>&6
+echo "configure:8009: checking for sasl_getprop in -lsasl2" >&5
+ac_lib_var=`echo sasl2'_'sasl_getprop | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsasl2 $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 8017 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char sasl_getprop();
+
+int main() {
+sasl_getprop()
+; return 0; }
+EOF
+if { (eval echo configure:8028: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SASL_LIB="-L${SASL_DIR}/lib -lsasl2"
+else
+ echo "$ac_t""no" 1>&6
+{ echo "configure: error: Can not find SASL" 1>&2; exit 1; }
+fi
+
+ LIBS=$inn_save_LIBS
+ cat >> confdefs.h <<\EOF
+#define HAVE_SASL 1
+EOF
+
+ fi
+fi
+
+
+if test x"${KRB5_INC}" != x; then
+inn_save_LIBS=$LIBS
+LIBS=${KRB5_LIB}
+
+echo $ac_n "checking for library containing krb5_parse_name""... $ac_c" 1>&6
+echo "configure:8063: checking for library containing krb5_parse_name" >&5
+if eval "test \"`echo '$''{'ac_cv_search_krb5_parse_name'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_krb5_parse_name="no"
+cat > conftest.$ac_ext <<EOF
+#line 8070 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char krb5_parse_name();
+
+int main() {
+krb5_parse_name()
+; return 0; }
+EOF
+if { (eval echo configure:8081: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_krb5_parse_name="none required"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_krb5_parse_name" = "no" && for i in krb5; do
+LIBS="-l$i $LIBS -lk5crypto -lcom_err $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 8092 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char krb5_parse_name();
+
+int main() {
+krb5_parse_name()
+; return 0; }
+EOF
+if { (eval echo configure:8103: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_krb5_parse_name="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_krb5_parse_name" 1>&6
+if test "$ac_cv_search_krb5_parse_name" != "no"; then
+ test "$ac_cv_search_krb5_parse_name" = "none required" || LIBS="$ac_cv_search_krb5_parse_name $LIBS"
+ KRB5_LIB=$LIBS
+ KRB5_AUTH="auth_krb5"
+ KRB5_LIB="$KRB5_LDFLAGS $KRB5_LIB -lk5crypto -lcom_err"
+
+
+ for ac_hdr in et/com_err.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:8128: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8133 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:8138: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+else :
+
+fi
+LIBS=$inn_save_LIBS
+
+
+inn_save_LIBS=$LIBS
+LIBS=$KRB5_LIB
+for ac_func in krb5_init_ets
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8175: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8180 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8203: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+fi # test x"${KRB5_INC}" != x;
+
+LIBS=$inn_save_LIBS
+
+if test x"$DO_PERL" = xDO ; then
+ echo $ac_n "checking for Perl linkage""... $ac_c" 1>&6
+echo "configure:8231: checking for Perl linkage" >&5
+ inn_perl_core_path=`$_PATH_PERL -MConfig -e 'print $Config{archlibexp}'`
+ inn_perl_core_flags=`$_PATH_PERL -MExtUtils::Embed -e ccopts`
+ inn_perl_core_libs=`$_PATH_PERL -MExtUtils::Embed -e ldopts 2>&1 | tail -1`
+ inn_perl_core_libs=" $inn_perl_core_libs "
+ inn_perl_core_libs=`echo "$inn_perl_core_libs" | sed 's/ -lc / /'`
+ for i in $LIBS ; do
+ inn_perl_core_libs=`echo "$inn_perl_core_libs" | sed "s/ $i / /"`
+ done
+ case $host in
+ *-linux*)
+ inn_perl_core_libs=`echo "$inn_perl_core_libs" | sed 's/ -lgdbm / /'`
+ ;;
+ *-cygwin*)
+ inn_perl_libname=`$_PATH_PERL -MConfig -e 'print $Config{libperl}'`
+ inn_perl_libname=`echo "$inn_perl_libname" | sed 's/^lib//; s/\.a$//'`
+ inn_perl_core_libs="${inn_perl_core_libs}-l$inn_perl_libname"
+ ;;
+ esac
+ inn_perl_core_libs=`echo "$inn_perl_core_libs" | sed 's/^ *//'`
+ inn_perl_core_libs=`echo "$inn_perl_core_libs" | sed 's/ *$//'`
+ inn_perl_core_flags=" $inn_perl_core_flags "
+ if test x"$inn_enable_largefiles" != xyes ; then
+ for f in -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES ; do
+ inn_perl_core_flags=`echo "$inn_perl_core_flags" | sed "s/ $f / /"`
+ done
+ fi
+ inn_perl_core_flags=`echo "$inn_perl_core_flags" | sed 's/^ *//'`
+ inn_perl_core_flags=`echo "$inn_perl_core_flags" | sed 's/ *$//'`
+ PERL_INC="$inn_perl_core_flags"
+ PERL_LIB="$inn_perl_core_libs"
+ echo "$ac_t""$inn_perl_core_path" 1>&6
+else
+ PERL_INC=''
+ PERL_LIB=''
+fi
+
+
+
+if test x"$DO_PYTHON" = xdefine ; then
+ echo $ac_n "checking for Python linkage""... $ac_c" 1>&6
+echo "configure:8272: checking for Python linkage" >&5
+ py_prefix=`$_PATH_PYTHON -c 'import sys; print sys.prefix'`
+ py_ver=`$_PATH_PYTHON -c 'import sys; print sys.version[:3]'`
+ py_libdir="${py_prefix}/lib/python${py_ver}"
+ PYTHON_INC="-I${py_prefix}/include/python${py_ver}"
+ py_linkage=""
+ for py_linkpart in LIBS LIBC LIBM LOCALMODLIBS BASEMODLIBS \
+ LINKFORSHARED LDFLAGS ; do
+ py_linkage="$py_linkage "`grep "^${py_linkpart}=" \
+ $py_libdir/config/Makefile \
+ | sed -e 's/^.*=//'`
+ done
+ PYTHON_LIB="-L$py_libdir/config -lpython$py_ver $py_linkage"
+ PYTHON_LIB=`echo $PYTHON_LIB | sed -e 's/ \\t*/ /g'`
+ echo "$ac_t""$py_libdir" 1>&6
+else
+ PYTHON_LIB=""
+ PYTHON_INC=""
+fi
+
+
+
+if test x"$inn_enable_largefiles" = xyes ; then
+ echo $ac_n "checking for largefile linkage""... $ac_c" 1>&6
+echo "configure:8296: checking for largefile linkage" >&5
+ case "$host" in
+ *-aix4.01*)
+ echo "$ac_t""no" 1>&6
+ { echo "configure: error: AIX before 4.2 does not support large files" 1>&2; exit 1; }
+ ;;
+ *-aix4*)
+ echo "$ac_t""ok" 1>&6
+ LFS_CFLAGS="-D_LARGE_FILES"
+ LFS_LDFLAGS=""
+ LFS_LIBS=""
+ ;;
+ *-hpux*)
+ echo "$ac_t""ok" 1>&6
+ LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+ LFS_LDFLAGS=""
+ LFS_LIBS=""
+ ;;
+ *-irix*)
+ echo "$ac_t""no" 1>&6
+ { echo "configure: error: Large files not supported on this platform" 1>&2; exit 1; }
+ ;;
+ *-linux*)
+ echo "$ac_t""maybe" 1>&6
+ LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+ LFS_LDFLAGS=""
+ LFS_LIBS=""
+ cat >> confdefs.h <<\EOF
+#define _GNU_SOURCE 1
+EOF
+
+ ;;
+ *-solaris*)
+ echo "$ac_t""ok" 1>&6
+ # Extract the first word of "getconf", so it can be a program name with args.
+set dummy getconf; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:8333: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GETCONF'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GETCONF" in
+ /*)
+ ac_cv_path_GETCONF="$GETCONF" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GETCONF="$GETCONF" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GETCONF="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+GETCONF="$ac_cv_path_GETCONF"
+if test -n "$GETCONF"; then
+ echo "$ac_t""$GETCONF" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$GETCONF" ; then
+ { echo "configure: error: getconf required to configure large file support" 1>&2; exit 1; }
+ fi
+ LFS_CFLAGS=`$GETCONF LFS_CFLAGS`
+ LFS_LDFLAGS=`$GETCONF LFS_LDFLAGS`
+ LFS_LIBS=`$GETCONF LFS_LIBS`
+ ;;
+ *)
+ echo "$ac_t""maybe" 1>&6
+ LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+ LFS_LDFLAGS=""
+ LFS_LIBS=""
+ ;;
+ esac
+
+
+
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:8385: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8390 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:8398: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 8415 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 8433 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8454 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:8465: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+
+if test x"$ac_cv_header_stdc" = xno ; then
+ for ac_hdr in memory.h stdlib.h strings.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:8494: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8499 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:8504: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in memcpy strchr
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:8533: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8538 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:8561: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:8592: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8597 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:8605: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:8630: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 8638 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:8649: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:8671: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 8679 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:8690: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:8713: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8718 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:8727: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:8748: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8753 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:8769: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+
+for ac_hdr in crypt.h inttypes.h limits.h ndbm.h pam/pam_appl.h stdbool.h \
+ stddef.h stdint.h string.h sys/bitypes.h sys/filio.h \
+ sys/loadavg.h sys/param.h sys/select.h sys/sysinfo.h \
+ sys/time.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:8797: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8802 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:8807: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+if test x"$ac_cv_header_ndbm_h" = xno ; then
+ for ac_hdr in db1/ndbm.h gdbm-ndbm.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:8839: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8844 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:8849: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+
+echo $ac_n "checking whether h_errno must be declared""... $ac_c" 1>&6
+echo "configure:8879: checking whether h_errno must be declared" >&5
+if eval "test \"`echo '$''{'inn_cv_herrno_need_decl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8884 "configure"
+#include "confdefs.h"
+#include <netdb.h>
+int main() {
+h_errno = 0;
+; return 0; }
+EOF
+if { (eval echo configure:8891: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_herrno_need_decl=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_herrno_need_decl=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_herrno_need_decl" 1>&6
+if test "$inn_cv_herrno_need_decl" = yes ; then
+ cat >> confdefs.h <<\EOF
+#define NEED_HERRNO_DECLARATION 1
+EOF
+
+fi
+
+
+
+
+echo $ac_n "checking whether inet_aton must be declared""... $ac_c" 1>&6
+echo "configure:8915: checking whether inet_aton must be declared" >&5
+if eval "test \"`echo '$''{'inn_cv_decl_needed_inet_aton'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8920 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+# if !HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#else
+# if HAVE_STRINGS_H
+# include <strings.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <netinet/in.h>
+#include <arpa/inet.h>
+int main() {
+char *(*pfn) = (char *(*)) inet_aton
+; return 0; }
+EOF
+if { (eval echo configure:8955: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_decl_needed_inet_aton=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_decl_needed_inet_aton=yes
+fi
+rm -f conftest*
+fi
+
+if test $inn_cv_decl_needed_inet_aton = yes ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_INET_ATON 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+echo $ac_n "checking whether inet_ntoa must be declared""... $ac_c" 1>&6
+echo "configure:8977: checking whether inet_ntoa must be declared" >&5
+if eval "test \"`echo '$''{'inn_cv_decl_needed_inet_ntoa'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8982 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+# if !HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#else
+# if HAVE_STRINGS_H
+# include <strings.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <netinet/in.h>
+#include <arpa/inet.h>
+int main() {
+char *(*pfn) = (char *(*)) inet_ntoa
+; return 0; }
+EOF
+if { (eval echo configure:9017: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_decl_needed_inet_ntoa=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_decl_needed_inet_ntoa=yes
+fi
+rm -f conftest*
+fi
+
+if test $inn_cv_decl_needed_inet_ntoa = yes ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_INET_NTOA 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+echo $ac_n "checking whether snprintf must be declared""... $ac_c" 1>&6
+echo "configure:9039: checking whether snprintf must be declared" >&5
+if eval "test \"`echo '$''{'inn_cv_decl_needed_snprintf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9044 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+# if !HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#else
+# if HAVE_STRINGS_H
+# include <strings.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+int main() {
+char *(*pfn) = (char *(*)) snprintf
+; return 0; }
+EOF
+if { (eval echo configure:9078: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_decl_needed_snprintf=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_decl_needed_snprintf=yes
+fi
+rm -f conftest*
+fi
+
+if test $inn_cv_decl_needed_snprintf = yes ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_SNPRINTF 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+echo $ac_n "checking whether vsnprintf must be declared""... $ac_c" 1>&6
+echo "configure:9100: checking whether vsnprintf must be declared" >&5
+if eval "test \"`echo '$''{'inn_cv_decl_needed_vsnprintf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9105 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+# if !HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#else
+# if HAVE_STRINGS_H
+# include <strings.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+int main() {
+char *(*pfn) = (char *(*)) vsnprintf
+; return 0; }
+EOF
+if { (eval echo configure:9139: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_decl_needed_vsnprintf=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_decl_needed_vsnprintf=yes
+fi
+rm -f conftest*
+fi
+
+if test $inn_cv_decl_needed_vsnprintf = yes ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_VSNPRINTF 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:9162: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 9169 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:9180: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 9184 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:9195: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_bigendian=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9215 "configure"
+#include "confdefs.h"
+main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:9228: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_bigendian=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+ cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:9252: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9257 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:9306: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6
+echo "configure:9327: checking for st_blksize in struct stat" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9332 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+int main() {
+struct stat s; s.st_blksize;
+; return 0; }
+EOF
+if { (eval echo configure:9340: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_st_blksize=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_st_blksize=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_st_blksize" 1>&6
+if test $ac_cv_struct_st_blksize = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ST_BLKSIZE 1
+EOF
+
+fi
+
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:9361: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9366 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:9374: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tm=time.h
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+ cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:9395: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9400 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:9428: checking for uid_t in sys/types.h" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9433 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "uid_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_uid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+if test $ac_cv_type_uid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:9462: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9467 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:9495: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9500 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for ptrdiff_t""... $ac_c" 1>&6
+echo "configure:9528: checking for ptrdiff_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_ptrdiff_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9533 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])ptrdiff_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_ptrdiff_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_ptrdiff_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_ptrdiff_t" 1>&6
+if test $ac_cv_type_ptrdiff_t = no; then
+ cat >> confdefs.h <<\EOF
+#define ptrdiff_t long
+EOF
+
+fi
+
+echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
+echo "configure:9561: checking for ssize_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9566 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])ssize_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_ssize_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_ssize_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_ssize_t" 1>&6
+if test $ac_cv_type_ssize_t = no; then
+ cat >> confdefs.h <<\EOF
+#define ssize_t int
+EOF
+
+fi
+
+
+
+echo $ac_n "checking for C99 variadic macros""... $ac_c" 1>&6
+echo "configure:9596: checking for C99 variadic macros" >&5
+if eval "test \"`echo '$''{'inn_cv_c_c99_vamacros'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9601 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#define error(...) fprintf(stderr, __VA_ARGS__)
+int main() {
+error("foo"); error("foo %d", 0); return 0;
+; return 0; }
+EOF
+if { (eval echo configure:9609: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_c_c99_vamacros=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_c_c99_vamacros=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_c_c99_vamacros" 1>&6
+if test $inn_cv_c_c99_vamacros = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_C99_VAMACROS 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for GNU-style variadic macros""... $ac_c" 1>&6
+echo "configure:9631: checking for GNU-style variadic macros" >&5
+if eval "test \"`echo '$''{'inn_cv_c_gnu_vamacros'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9636 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#define error(args...) fprintf(stderr, args)
+int main() {
+error("foo"); error("foo %d", 0); return 0;
+; return 0; }
+EOF
+if { (eval echo configure:9644: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_c_gnu_vamacros=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_c_gnu_vamacros=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_c_gnu_vamacros" 1>&6
+if test $inn_cv_c_gnu_vamacros = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GNU_VAMACROS 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for long long int""... $ac_c" 1>&6
+echo "configure:9666: checking for long long int" >&5
+if eval "test \"`echo '$''{'inn_cv_c_long_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9671 "configure"
+#include "confdefs.h"
+
+int main() {
+long long int i;
+; return 0; }
+EOF
+if { (eval echo configure:9678: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_c_long_long=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_c_long_long=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_c_long_long" 1>&6
+if test $inn_cv_c_long_long = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LONG_LONG 1
+EOF
+
+fi
+
+
+
+
+echo $ac_n "checking for sig_atomic_t""... $ac_c" 1>&6
+echo "configure:9702: checking for sig_atomic_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_sig_atomic_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9707 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#endif
+#include <signal.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])sig_atomic_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_sig_atomic_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_sig_atomic_t=no
+
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_sig_atomic_t" 1>&6
+if test x"$ac_cv_type_sig_atomic_t" = xno ; then
+ cat >> confdefs.h <<EOF
+#define sig_atomic_t int
+EOF
+
+fi
+
+echo $ac_n "checking for socklen_t""... $ac_c" 1>&6
+echo "configure:9738: checking for socklen_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9743 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#endif
+#include <sys/socket.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])socklen_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_socklen_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_socklen_t=no
+
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_socklen_t" 1>&6
+if test x"$ac_cv_type_socklen_t" = xno ; then
+ cat >> confdefs.h <<EOF
+#define socklen_t int
+EOF
+
+fi
+
+
+
+
+echo $ac_n "checking value of IOV_MAX""... $ac_c" 1>&6
+echo "configure:9777: checking value of IOV_MAX" >&5
+if eval "test \"`echo '$''{'inn_cv_macro_iov_max'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ 16
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9785 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <stdio.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <fcntl.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+int
+main ()
+{
+ int fd, size;
+ struct iovec array[1024];
+ char data;
+
+ FILE *f = fopen ("conftestval", "w");
+ if (!f) return 1;
+#ifdef IOV_MAX
+ fprintf (f, "set in limits.h\n");
+#else
+# ifdef UIO_MAXIOV
+ fprintf (f, "%d\n", UIO_MAXIOV);
+# else
+ fd = open ("/dev/null", O_WRONLY, 0666);
+ if (fd < 0) return 1;
+ for (size = 1; size <= 1024; size++)
+ {
+ array[size - 1].iov_base = &data;
+ array[size - 1].iov_len = sizeof data;
+ if (writev (fd, array, size) < 0)
+ {
+ if (errno != EINVAL) return 1;
+ fprintf(f, "%d\n", size - 1);
+ exit (0);
+ }
+ }
+ fprintf (f, "1024\n");
+# endif /* UIO_MAXIOV */
+#endif /* IOV_MAX */
+ return 0;
+}
+EOF
+if { (eval echo configure:9833: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ inn_cv_macro_iov_max=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ inn_cv_macro_iov_max=error
+fi
+rm -fr conftest*
+fi
+
+if test x"$inn_cv_macro_iov_max" = xerror ; then
+ echo "configure: warning: probe failure, assuming 16" 1>&2
+ inn_cv_macro_iov_max=16
+fi
+fi
+
+echo "$ac_t""$inn_cv_macro_iov_max" 1>&6
+if test x"$inn_cv_macro_iov_max" != x"set in limits.h" ; then
+ cat >> confdefs.h <<EOF
+#define IOV_MAX $inn_cv_macro_iov_max
+EOF
+
+fi
+
+
+echo $ac_n "checking for SUN_LEN""... $ac_c" 1>&6
+echo "configure:9861: checking for SUN_LEN" >&5
+if eval "test \"`echo '$''{'inn_cv_macro_sun_len'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9866 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/un.h>
+int main() {
+struct sockaddr_un sun;
+int i;
+
+i = SUN_LEN(&sun);
+; return 0; }
+EOF
+if { (eval echo configure:9877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ inn_cv_macro_sun_len=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_macro_sun_len=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_macro_sun_len" 1>&6
+if test x"$inn_cv_macro_sun_len" = xyes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SUN_LEN 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for tm_gmtoff in struct tm""... $ac_c" 1>&6
+echo "configure:9899: checking for tm_gmtoff in struct tm" >&5
+if eval "test \"`echo '$''{'inn_cv_struct_tm_gmtoff'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9904 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+struct tm t; t.tm_gmtoff = 3600
+; return 0; }
+EOF
+if { (eval echo configure:9911: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ inn_cv_struct_tm_gmtoff=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_struct_tm_gmtoff=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_struct_tm_gmtoff" 1>&6
+if test x"$inn_cv_struct_tm_gmtoff" = xyes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TM_GMTOFF 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6
+echo "configure:9933: checking for tm_zone in struct tm" >&5
+if eval "test \"`echo '$''{'inn_cv_struct_tm_zone'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9938 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+struct tm t; t.tm_zone = "UTC"
+; return 0; }
+EOF
+if { (eval echo configure:9945: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ inn_cv_struct_tm_zone=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_struct_tm_zone=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_struct_tm_zone" 1>&6
+if test x"$inn_cv_struct_tm_zone" = xyes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TM_ZONE 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for timezone variable""... $ac_c" 1>&6
+echo "configure:9967: checking for timezone variable" >&5
+if eval "test \"`echo '$''{'inn_cv_var_timezone'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9972 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+timezone = 3600; altzone = 7200
+; return 0; }
+EOF
+if { (eval echo configure:9979: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ inn_cv_var_timezone=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_var_timezone=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_var_timezone" 1>&6
+if test x"$inn_cv_var_timezone" = xyes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_VAR_TIMEZONE 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for tzname variable""... $ac_c" 1>&6
+echo "configure:10001: checking for tzname variable" >&5
+if eval "test \"`echo '$''{'inn_cv_var_tzname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10006 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+*tzname = "UTC"
+; return 0; }
+EOF
+if { (eval echo configure:10013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ inn_cv_var_tzname=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_var_tzname=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_var_tzname" 1>&6
+if test x"$inn_cv_var_tzname" = xyes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_VAR_TZNAME 1
+EOF
+
+fi
+
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:10036: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_int=4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10044 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f = fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(int));
+ exit(0);
+}
+EOF
+if { (eval echo configure:10055: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_int=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+if test x"$ac_cv_sizeof_int" = x"4" ; then
+ INN_INT32=int
+else
+ echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:10074: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_long=4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10082 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f = fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(long));
+ exit(0);
+}
+EOF
+if { (eval echo configure:10093: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_long=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_long=0
+fi
+rm -fr conftest*
+fi
+
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+if test x"$ac_cv_sizeof_long" = x"4" ; then
+ INN_INT32=long
+else
+ echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:10112: checking size of short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_short=2
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10120 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f = fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(short));
+ exit(0);
+}
+EOF
+if { (eval echo configure:10131: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_short=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_short=0
+fi
+rm -fr conftest*
+fi
+
+
+fi
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+if test x"$ac_cv_sizeof_short" = x"4" ; then
+ INN_INT32=short
+else
+ :
+fi
+
+fi
+
+fi
+
+
+echo $ac_n "checking for int32_t""... $ac_c" 1>&6
+echo "configure:10158: checking for int32_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_int32_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10163 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+# include <sys/bitypes.h>
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])int32_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_int32_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_int32_t=no
+
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_int32_t" 1>&6
+if test x"$ac_cv_type_int32_t" = xno ; then
+ cat >> confdefs.h <<EOF
+#define int32_t $INN_INT32
+EOF
+
+fi
+
+
+echo $ac_n "checking for uint32_t""... $ac_c" 1>&6
+echo "configure:10201: checking for uint32_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uint32_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10206 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+# include <sys/bitypes.h>
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])uint32_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_uint32_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_uint32_t=no
+
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uint32_t" 1>&6
+if test x"$ac_cv_type_uint32_t" = xno ; then
+ cat >> confdefs.h <<EOF
+#define uint32_t unsigned $INN_INT32
+EOF
+
+fi
+
+echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
+echo "configure:10243: checking for 8-bit clean memcmp" >&5
+if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_memcmp_clean=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10251 "configure"
+#include "confdefs.h"
+
+main()
+{
+ char c0 = 0x40, c1 = 0x80, c2 = 0x81;
+ exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1);
+}
+
+EOF
+if { (eval echo configure:10261: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_memcmp_clean=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_memcmp_clean=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
+test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:10279: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10284 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:10301: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+
+
+
+
+echo $ac_n "checking for working inet_ntoa""... $ac_c" 1>&6
+echo "configure:10324: checking for working inet_ntoa" >&5
+if eval "test \"`echo '$''{'inn_cv_func_inet_ntoa_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ inn_cv_func_inet_ntoa_works=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10332 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#if STDC_HEADERS || HAVE_STRING_H
+# include <string.h>
+#endif
+
+int
+main ()
+{
+ struct in_addr in;
+ in.s_addr = htonl (0x7f000000L);
+ return (!strcmp (inet_ntoa (in), "127.0.0.0") ? 0 : 1);
+}
+EOF
+if { (eval echo configure:10350: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ inn_cv_func_inet_ntoa_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ inn_cv_func_inet_ntoa_works=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$inn_cv_func_inet_ntoa_works" 1>&6
+if test "$inn_cv_func_inet_ntoa_works" = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_INET_NTOA 1
+EOF
+
+else
+ LIBOBJS="$LIBOBJS inet_ntoa.${ac_objext}"
+fi
+
+
+echo $ac_n "checking whether struct sockaddr has sa_len""... $ac_c" 1>&6
+echo "configure:10376: checking whether struct sockaddr has sa_len" >&5
+if eval "test \"`echo '$''{'inn_cv_struct_sockaddr_sa_len'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10381 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+int main() {
+struct sockaddr sa; int x = sa.sa_len;
+; return 0; }
+EOF
+if { (eval echo configure:10390: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_struct_sockaddr_sa_len=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_struct_sockaddr_sa_len=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_struct_sockaddr_sa_len" 1>&6
+if test "$inn_cv_struct_sockaddr_sa_len" = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SOCKADDR_LEN 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for SA_LEN(s) macro""... $ac_c" 1>&6
+echo "configure:10412: checking for SA_LEN(s) macro" >&5
+if eval "test \"`echo '$''{'inn_cv_sa_len_macro'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10417 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+int main() {
+struct sockaddr sa; int x = SA_LEN(&sa);
+; return 0; }
+EOF
+if { (eval echo configure:10426: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ inn_cv_sa_len_macro=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_sa_len_macro=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_sa_len_macro" 1>&6
+if test "$inn_cv_sa_len_macro" = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SA_LEN_MACRO 1
+EOF
+
+fi
+
+
+
+
+echo $ac_n "checking for struct sockaddr_storage""... $ac_c" 1>&6
+echo "configure:10450: checking for struct sockaddr_storage" >&5
+if eval "test \"`echo '$''{'inn_cv_struct_sockaddr_storage'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10455 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+int main() {
+struct sockaddr_storage ss;
+; return 0; }
+EOF
+if { (eval echo configure:10464: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_struct_sockaddr_storage=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_struct_sockaddr_storage=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_struct_sockaddr_storage" 1>&6
+if test "$inn_cv_struct_sockaddr_storage" = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SOCKADDR_STORAGE 1
+EOF
+
+ echo $ac_n "checking for RFC 2553 style sockaddr_storage member names""... $ac_c" 1>&6
+echo "configure:10483: checking for RFC 2553 style sockaddr_storage member names" >&5
+if eval "test \"`echo '$''{'inn_cv_2553_ss_family'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10488 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+int main() {
+struct sockaddr_storage ss; int x=ss.ss_family;
+; return 0; }
+EOF
+if { (eval echo configure:10497: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_2553_ss_family=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_2553_ss_family=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_2553_ss_family" 1>&6
+if test "$inn_cv_2553_ss_family" = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_2553_STYLE_SS_FAMILY 1
+EOF
+
+fi
+fi
+
+
+
+
+if test "$inn_enable_ipv6_tests" = yes ; then
+ echo $ac_n "checking whether IN6_ARE_ADDR_EQUAL macro is broken""... $ac_c" 1>&6
+echo "configure:10523: checking whether IN6_ARE_ADDR_EQUAL macro is broken" >&5
+if eval "test \"`echo '$''{'inn_cv_in6_are_addr_equal_broken'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ inn_cv_in6_are_addr_equal_broken=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10531 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int
+main ()
+{
+ struct in6_addr a;
+ struct in6_addr b;
+
+ inet_pton(AF_INET6,"fe80::1234:5678:abcd",&a);
+ inet_pton(AF_INET6,"fe80::1234:5678:abcd",&b);
+ return IN6_ARE_ADDR_EQUAL(&a,&b) ? 0 : 1;
+}
+EOF
+if { (eval echo configure:10549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ inn_cv_in6_are_addr_equal_broken=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ inn_cv_in6_are_addr_equal_broken=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$inn_cv_in6_are_addr_equal_broken" 1>&6
+if test "$inn_cv_in6_are_addr_equal_broken" = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_BROKEN_IN6_ARE_ADDR_EQUAL 1
+EOF
+
+fi
+fi
+
+
+
+
+echo $ac_n "checking for working snprintf""... $ac_c" 1>&6
+echo "configure:10576: checking for working snprintf" >&5
+if eval "test \"`echo '$''{'inn_cv_func_snprintf_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ inn_cv_func_snprintf_works=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10584 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+char buf[2];
+
+int
+test (char *format, ...)
+{
+ va_list args;
+ int count;
+
+ va_start (args, format);
+ count = vsnprintf (buf, sizeof buf, format, args);
+ va_end (args);
+ return count;
+}
+
+int
+main ()
+{
+ return ((test ("%s", "abcd") == 4 && buf[0] == 'a' && buf[1] == '\0'
+ && snprintf(NULL, 0, "%s", "abcd") == 4) ? 0 : 1);
+}
+EOF
+if { (eval echo configure:10610: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ inn_cv_func_snprintf_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ inn_cv_func_snprintf_works=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$inn_cv_func_snprintf_works" 1>&6
+if test "$inn_cv_func_snprintf_works" = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SNPRINTF 1
+EOF
+
+else
+ LIBOBJS="$LIBOBJS snprintf.${ac_objext}"
+fi
+
+for ac_func in atexit getloadavg getrlimit getrusage getspnam setbuffer \
+ sigaction setgroups setrlimit setsid socketpair statvfs \
+ strncasecmp strtoul symlink sysconf
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:10639: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10644 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:10667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+if test x"$ac_cv_func_getrlimit" = xno ; then
+ for ac_func in getdtablesize ulimit
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:10696: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10701 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:10724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+if test x"$ac_cv_func_statvfs" = xno ; then
+ for ac_func in statfs
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:10754: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10759 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:10782: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_hdr in sys/vfs.h sys/mount.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:10810: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10815 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:10820: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+for ac_func in fseeko ftello getpagesize hstrerror inet_aton mkstemp \
+ pread pwrite seteuid strcasecmp strerror strlcat strlcpy \
+ strspn setenv
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:10853: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10858 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:10881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}"
+fi
+done
+
+
+
+
+
+
+
+if test "$ac_cv_func_fseeko" = no || test "$ac_cv_func_ftello" = no ; then
+ echo $ac_n "checking for off_t-compatible fpos_t""... $ac_c" 1>&6
+echo "configure:10914: checking for off_t-compatible fpos_t" >&5
+if eval "test \"`echo '$''{'inn_cv_type_fpos_t_large'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ inn_cv_type_fpos_t_large=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10922 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+
+int
+main ()
+{
+ fpos_t fpos = 9223372036854775807ULL;
+ off_t off;
+ off = fpos;
+ exit(off == (off_t) 9223372036854775807ULL ? 0 : 1);
+}
+EOF
+if { (eval echo configure:10936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ inn_cv_type_fpos_t_large=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ inn_cv_type_fpos_t_large=no
+fi
+rm -fr conftest*
+fi
+
+if test "$inn_cv_type_fpos_t_large" = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LARGE_FPOS_T 1
+EOF
+
+fi
+fi
+
+echo "$ac_t""$inn_cv_type_fpos_t_large" 1>&6
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:10975: checking for working mmap" >&5
+if eval "test \"`echo '$''{'inn_cv_func_mmap'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ inn_cv_func_mmap=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 10983 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+# if !HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#else
+# if HAVE_STRINGS_H
+# include <strings.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <sys/mman.h>
+
+int
+main()
+{
+ int *data, *data2;
+ int i, fd;
+
+ /* First, make a file with some known garbage in it. Use something
+ larger than one page but still an odd page size. */
+ data = malloc (20000);
+ if (!data) return 1;
+ for (i = 0; i < 20000 / sizeof (int); i++)
+ data[i] = rand();
+ umask (0);
+ fd = creat ("conftestmmaps", 0600);
+ if (fd < 0) return 1;
+ if (write (fd, data, 20000) != 20000) return 1;
+ close (fd);
+
+ /* Next, try to mmap the file and make sure we see the same garbage. */
+ fd = open ("conftestmmaps", O_RDWR);
+ if (fd < 0) return 1;
+ data2 = mmap (0, 20000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (data2 == (int *) -1) return 1;
+ for (i = 0; i < 20000 / sizeof (int); i++)
+ if (data[i] != data2[i])
+ return 1;
+
+ close (fd);
+ unlink ("conftestmmaps");
+ return 0;
+}
+EOF
+if { (eval echo configure:11047: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ inn_cv_func_mmap=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ inn_cv_func_mmap=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$inn_cv_func_mmap" 1>&6
+if test $inn_cv_func_mmap = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+if test x"$inn_cv_func_mmap" = xyes ; then
+ for ac_func in madvise
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:11072: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11077 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:11100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ echo $ac_n "checking whether mmap sees writes""... $ac_c" 1>&6
+echo "configure:11125: checking whether mmap sees writes" >&5
+if eval "test \"`echo '$''{'inn_cv_func_mmap_sees_writes'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ inn_cv_func_mmap_sees_writes=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11133 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <sys/mman.h>
+
+/* Fractional page is probably worst case. */
+static char zbuff[1024];
+static char fname[] = "conftestw";
+
+int
+main ()
+{
+ char *map;
+ int i, fd;
+
+ fd = open (fname, O_RDWR | O_CREAT, 0660);
+ if (fd < 0) return 1;
+ unlink (fname);
+ write (fd, zbuff, sizeof (zbuff));
+ lseek (fd, 0, SEEK_SET);
+ map = mmap (0, sizeof (zbuff), PROT_READ, MAP_SHARED, fd, 0);
+ if (map == (char *) -1) return 2;
+ for (i = 0; fname[i]; i++)
+ {
+ if (write (fd, &fname[i], 1) != 1) return 3;
+ if (map[i] != fname[i]) return 4;
+ }
+ return 0;
+}
+EOF
+if { (eval echo configure:11169: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ inn_cv_func_mmap_sees_writes=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ inn_cv_func_mmap_sees_writes=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$inn_cv_func_mmap_sees_writes" 1>&6
+if test $inn_cv_func_mmap_sees_writes = no ; then
+ cat >> confdefs.h <<\EOF
+#define MMAP_MISSES_WRITES 1
+EOF
+
+fi
+ echo $ac_n "checking whether msync is needed""... $ac_c" 1>&6
+echo "configure:11191: checking whether msync is needed" >&5
+if eval "test \"`echo '$''{'inn_cv_func_mmap_need_msync'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ inn_cv_func_mmap_need_msync=yes
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11199 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+# if !HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#else
+# if HAVE_STRINGS_H
+# include <strings.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+int
+main()
+{
+ int *data, *data2;
+ int i, fd;
+
+ /* First, make a file with some known garbage in it. Use something
+ larger than one page but still an odd page size. */
+ data = malloc (20000);
+ if (!data) return 1;
+ for (i = 0; i < 20000 / sizeof (int); i++)
+ data[i] = rand();
+ umask (0);
+ fd = creat ("conftestmmaps", 0600);
+ if (fd < 0) return 1;
+ if (write (fd, data, 20000) != 20000) return 1;
+ close (fd);
+
+ /* Next, try to mmap the file and make sure we see the same garbage. */
+ fd = open ("conftestmmaps", O_RDWR);
+ if (fd < 0) return 1;
+ data2 = mmap (0, 20000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (data2 == (int *) -1) return 1;
+
+ /* Finally, see if changes made to the mmaped region propagate back to
+ the file as seen by read (meaning that msync isn't needed). */
+ for (i = 0; i < 20000 / sizeof (int); i++)
+ data2[i]++;
+ if (read (fd, data, 20000) != 20000) return 1;
+ for (i = 0; i < 20000 / sizeof (int); i++)
+ if (data[i] != data2[i])
+ return 1;
+
+ close (fd);
+ unlink ("conftestmmapm");
+ return 0;
+}
+EOF
+if { (eval echo configure:11270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ inn_cv_func_mmap_need_msync=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ inn_cv_func_mmap_need_msync=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$inn_cv_func_mmap_need_msync" 1>&6
+if test $inn_cv_func_mmap_need_msync = yes ; then
+ cat >> confdefs.h <<\EOF
+#define MMAP_NEEDS_MSYNC 1
+EOF
+
+fi
+ echo $ac_n "checking how many arguments msync takes""... $ac_c" 1>&6
+echo "configure:11292: checking how many arguments msync takes" >&5
+if eval "test \"`echo '$''{'inn_cv_func_msync_args'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11297 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/mman.h>
+int main() {
+char *p; int psize; msync (p, psize, MS_ASYNC);
+; return 0; }
+EOF
+if { (eval echo configure:11305: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ inn_cv_func_msync_args=3
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ inn_cv_func_msync_args=2
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$inn_cv_func_msync_args" 1>&6
+if test $inn_cv_func_msync_args = 3 ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MSYNC_3_ARG 1
+EOF
+
+fi
+fi
+
+
+echo $ac_n "checking for Unix domain sockets""... $ac_c" 1>&6
+echo "configure:11328: checking for Unix domain sockets" >&5
+if eval "test \"`echo '$''{'inn_cv_sys_unix_sockets'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11333 "configure"
+#include "confdefs.h"
+#include <sys/socket.h>
+#ifdef AF_UNIX
+yes
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ inn_cv_sys_unix_sockets=yes
+else
+ rm -rf conftest*
+ inn_cv_sys_unix_sockets=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$inn_cv_sys_unix_sockets" 1>&6
+if test $inn_cv_sys_unix_sockets = yes ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_UNIX_DOMAIN_SOCKETS 1
+EOF
+
+fi
+
+
+echo $ac_n "checking log facility for news""... $ac_c" 1>&6
+echo "configure:11362: checking log facility for news" >&5
+if eval "test \"`echo '$''{'inn_cv_log_facility'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 11367 "configure"
+#include "confdefs.h"
+#include <syslog.h>
+#ifdef LOG_NEWS
+yes
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ inn_cv_log_facility=LOG_NEWS
+else
+ rm -rf conftest*
+ inn_cv_log_facility=LOG_LOCAL1
+fi
+rm -f conftest*
+
+fi
+
+if test x"$SYSLOG_FACILITY" = xnone ; then
+ SYSLOG_FACILITY=$inn_cv_log_facility
+fi
+echo "$ac_t""$SYSLOG_FACILITY" 1>&6
+cat >> confdefs.h <<EOF
+#define LOG_INN_SERVER $SYSLOG_FACILITY
+EOF
+
+cat >> confdefs.h <<EOF
+#define LOG_INN_PROG $SYSLOG_FACILITY
+EOF
+
+
+
+LIBS=`echo "$LIBS" | sed 's/^ *//' | sed 's/ */ /g' | sed 's/ *$//'`
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile.global
+ include/paths.h
+ samples/inn.conf
+ samples/innreport.conf
+ samples/newsfeeds
+ samples/sasl.conf
+ scripts/inncheck
+ scripts/innshellvars
+ scripts/innshellvars.pl
+ scripts/innshellvars.tcl
+ scripts/news.daily
+ support/fixscript
+ include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@builddir@%$builddir%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@OBJEXT@%$OBJEXT%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@LN_S@%$LN_S%g
+s%@EXEEXT@%$EXEEXT%g
+s%@ECHO@%$ECHO%g
+s%@RANLIB@%$RANLIB%g
+s%@STRIP@%$STRIP%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@EXTLIB@%$EXTLIB%g
+s%@EXTOBJ@%$EXTOBJ%g
+s%@LIBTOOLCC@%$LIBTOOLCC%g
+s%@LIBTOOLLD@%$LIBTOOLLD%g
+s%@CCOUTPUT@%$CCOUTPUT%g
+s%@CONTROLDIR@%$CONTROLDIR%g
+s%@DBDIR@%$DBDIR%g
+s%@DOCDIR@%$DOCDIR%g
+s%@ETCDIR@%$ETCDIR%g
+s%@FILTERDIR@%$FILTERDIR%g
+s%@LIBDIR@%$LIBDIR%g
+s%@LOGDIR@%$LOGDIR%g
+s%@RUNDIR@%$RUNDIR%g
+s%@SPOOLDIR@%$SPOOLDIR%g
+s%@tmpdir@%$tmpdir%g
+s%@NEWSUSER@%$NEWSUSER%g
+s%@NEWSGRP@%$NEWSGRP%g
+s%@NEWSMASTER@%$NEWSMASTER%g
+s%@NEWSUMASK@%$NEWSUMASK%g
+s%@FILEMODE@%$FILEMODE%g
+s%@DIRMODE@%$DIRMODE%g
+s%@RUNDIRMODE@%$RUNDIRMODE%g
+s%@INEWSMODE@%$INEWSMODE%g
+s%@RNEWSGRP@%$RNEWSGRP%g
+s%@RNEWSMODE@%$RNEWSMODE%g
+s%@LOG_COMPRESS@%$LOG_COMPRESS%g
+s%@LOG_COMPRESSEXT@%$LOG_COMPRESSEXT%g
+s%@DO_DBZ_TAGGED_HASH@%$DO_DBZ_TAGGED_HASH%g
+s%@HOSTNAME@%$HOSTNAME%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@YACC@%$YACC%g
+s%@CTAGS@%$CTAGS%g
+s%@_PATH_AWK@%$_PATH_AWK%g
+s%@_PATH_EGREP@%$_PATH_EGREP%g
+s%@_PATH_PERL@%$_PATH_PERL%g
+s%@_PATH_SH@%$_PATH_SH%g
+s%@_PATH_SED@%$_PATH_SED%g
+s%@_PATH_SORT@%$_PATH_SORT%g
+s%@_PATH_UUX@%$_PATH_UUX%g
+s%@PATH_GPGV@%$PATH_GPGV%g
+s%@_PATH_PGP@%$_PATH_PGP%g
+s%@pgpverify@%$pgpverify%g
+s%@GETFTP@%$GETFTP%g
+s%@COMPRESS@%$COMPRESS%g
+s%@GZIP@%$GZIP%g
+s%@UNCOMPRESS@%$UNCOMPRESS%g
+s%@SENDMAIL@%$SENDMAIL%g
+s%@HAVE_UUSTAT@%$HAVE_UUSTAT%g
+s%@_PATH_PYTHON@%$_PATH_PYTHON%g
+s%@CRYPT_LIB@%$CRYPT_LIB%g
+s%@SHADOW_LIB@%$SHADOW_LIB%g
+s%@PAM_LIB@%$PAM_LIB%g
+s%@REGEX_LIB@%$REGEX_LIB%g
+s%@BERKELEY_DB_LDFLAGS@%$BERKELEY_DB_LDFLAGS%g
+s%@BERKELEY_DB_CFLAGS@%$BERKELEY_DB_CFLAGS%g
+s%@BERKELEY_DB_LIB@%$BERKELEY_DB_LIB%g
+s%@DBM_LIB@%$DBM_LIB%g
+s%@DBM_INC@%$DBM_INC%g
+s%@SSL_BIN@%$SSL_BIN%g
+s%@SSL_INC@%$SSL_INC%g
+s%@SSL_LIB@%$SSL_LIB%g
+s%@SASL_INC@%$SASL_INC%g
+s%@SASL_LIB@%$SASL_LIB%g
+s%@KRB5_AUTH@%$KRB5_AUTH%g
+s%@KRB5_INC@%$KRB5_INC%g
+s%@KRB5_LIB@%$KRB5_LIB%g
+s%@PERL_INC@%$PERL_INC%g
+s%@PERL_LIB@%$PERL_LIB%g
+s%@PYTHON_LIB@%$PYTHON_LIB%g
+s%@PYTHON_INC@%$PYTHON_INC%g
+s%@GETCONF@%$GETCONF%g
+s%@LFS_CFLAGS@%$LFS_CFLAGS%g
+s%@LFS_LDFLAGS@%$LFS_LDFLAGS%g
+s%@LFS_LIBS@%$LFS_LIBS%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@SYSLOG_FACILITY@%$SYSLOG_FACILITY%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile.global
+ include/paths.h
+ samples/inn.conf
+ samples/innreport.conf
+ samples/newsfeeds
+ samples/sasl.conf
+ scripts/inncheck
+ scripts/innshellvars
+ scripts/innshellvars.pl
+ scripts/innshellvars.tcl
+ scripts/news.daily
+ support/fixscript
+ "}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="include/config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+chmod +x support/fixscript
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
+cat <<EOM
+
+Please check the following files before running make, to ensure that
+everything was set correctly.
+
+ Makefile.global
+ include/config.h
+ include/paths.h
+ innfeed/innfeed.h
+
+EOM
+
+if $_PATH_PERL -e "exit((stat('$tmpdir'))[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
--- /dev/null
+#
+# overview buffer configuration file
+#
+# The order in this items appear in this file is not important
+
+# Format:
+# index(0-65535) : path to buffer file :
+# length of buffer in kilobytes in decimal (1KB = 1024 bytes)
+
+0:/var/news/spool/overview/OV1:1536000
+1:/var/news/spool/overview/OV2:1536000
--- /dev/null
+/* $Id: art.c 7748 2008-04-06 13:49:56Z iulius $
+**
+** Article-processing.
+*/
+
+#include "config.h"
+#include "clibrary.h"
+#include <sys/uio.h>
+
+#include "inn/innconf.h"
+#include "inn/wire.h"
+#include "inn/md5.h"
+#include "innd.h"
+#include "ov.h"
+#include "storage.h"
+
+typedef struct iovec IOVEC;
+
+#define ARTIOVCNT 16
+
+extern bool DoCancels;
+
+#if defined(S_IXUSR)
+#define EXECUTE_BITS (S_IXUSR | S_IXGRP | S_IXOTH)
+#else
+#define EXECUTE_BITS 0111
+#endif /* defined(S_IXUSR) */
+
+/* Characters used in log messages indicating the disposition of messages. */
+#define ART_ACCEPT '+'
+#define ART_CANC 'c'
+#define ART_STRSTR '?'
+#define ART_JUNK 'j'
+#define ART_REJECT '-'
+
+/*
+** used to sort Xref, Bytes and Path pointers
+*/
+typedef struct _HEADERP {
+ int index;
+ char *p;
+} HEADERP;
+
+#define HPCOUNT 4
+
+/*
+** For speed we build a binary tree of the headers, sorted by their
+** name. We also store the header's Name fields in the tree to avoid
+** doing an extra indirection.
+*/
+typedef struct _TREE {
+ const char *Name;
+ const ARTHEADER *Header;
+ struct _TREE *Before;
+ struct _TREE *After;
+} TREE;
+
+static TREE *ARTheadertree;
+
+/*
+** For doing the overview database, we keep a list of the headers and
+** a flag saying if they're written in brief or full format.
+*/
+typedef struct _ARTOVERFIELD {
+ const ARTHEADER *Header;
+ bool NeedHeader;
+} ARTOVERFIELD;
+
+static ARTOVERFIELD *ARTfields;
+
+/*
+** General newsgroup we care about, and what we put in the Path line.
+*/
+static char ARTctl[] = "control";
+static char ARTjnk[] = "junk";
+static char *ARTpathme;
+
+/*
+** Different types of rejected articles.
+*/
+typedef enum {REJECT_DUPLICATE, REJECT_SITE, REJECT_FILTER, REJECT_DISTRIB,
+ REJECT_GROUP, REJECT_UNAPP, REJECT_OTHER} Reject_type;
+
+/*
+** Flag array, indexed by character. Character classes for Message-ID's.
+*/
+static char ARTcclass[256];
+#define CC_MSGID_ATOM 01
+#define CC_MSGID_NORM 02
+#define CC_HOSTNAME 04
+#define ARTnormchar(c) ((ARTcclass[(unsigned char)(c)] & CC_MSGID_NORM) != 0)
+#define ARTatomchar(c) ((ARTcclass[(unsigned char)(c)] & CC_MSGID_ATOM) != 0)
+#define ARThostchar(c) ((ARTcclass[(unsigned char)(c)] & CC_HOSTNAME) != 0)
+
+#if defined(DO_PERL) || defined(DO_PYTHON)
+const char *filterPath;
+#endif /* DO_PERL || DO_PYTHON */
+
+
+\f
+/*
+** Trim '\r' from buffer.
+*/
+static void
+buffer_trimcr(struct buffer *bp)
+{
+ char *p, *q;
+ int trimmed = 0;
+
+ for (p = q = bp->data ; p < bp->data + bp->left ; p++) {
+ if (*p == '\r' && p+1 < bp->data + bp->left && p[1] == '\n') {
+ trimmed++;
+ continue;
+ }
+ *q++ = *p;
+ }
+ bp->left -= trimmed;
+}
+
+/*
+** Mark that the site gets this article.
+*/
+static void
+SITEmark(SITE *sp, NEWSGROUP *ngp)
+{
+ SITE *funnel;
+
+ sp->Sendit = true;
+ if (sp->ng == NULL)
+ sp->ng = ngp;
+ if (sp->Funnel != NOSITE) {
+ funnel = &Sites[sp->Funnel];
+ if (funnel->ng == NULL)
+ funnel->ng = ngp;
+ }
+}
+
+/*
+**
+*/
+bool
+ARTreadschema(void)
+{
+ static char *SCHEMA = NULL;
+ FILE *F;
+ int i;
+ char *p;
+ ARTOVERFIELD *fp;
+ const ARTHEADER *hp;
+ bool ok;
+ char buff[SMBUF];
+ bool foundxref = false;
+ bool foundxreffull = false;
+
+ if (ARTfields != NULL) {
+ free(ARTfields);
+ ARTfields = NULL;
+ }
+
+ /* Open file, count lines. */
+ if (SCHEMA == NULL)
+ SCHEMA = concatpath(innconf->pathetc, _PATH_SCHEMA);
+ if ((F = Fopen(SCHEMA, "r", TEMPORARYOPEN)) == NULL)
+ return false;
+ for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++)
+ continue;
+ fseeko(F, 0, SEEK_SET);
+ ARTfields = xmalloc((i + 1) * sizeof(ARTOVERFIELD));
+
+ /* Parse each field. */
+ for (ok = true, fp = ARTfields ; fgets(buff, sizeof buff, F) != NULL ;) {
+ /* Ignore blank and comment lines. */
+ if ((p = strchr(buff, '\n')) != NULL)
+ *p = '\0';
+ if ((p = strchr(buff, '#')) != NULL)
+ *p = '\0';
+ if (buff[0] == '\0')
+ continue;
+ if ((p = strchr(buff, ':')) != NULL) {
+ *p++ = '\0';
+ fp->NeedHeader = (strcmp(p, "full") == 0);
+ } else
+ fp->NeedHeader = false;
+ if (strcasecmp(buff, "Xref") == 0) {
+ foundxref = true;
+ foundxreffull = fp->NeedHeader;
+ }
+ for (hp = ARTheaders; hp < ARRAY_END(ARTheaders); hp++) {
+ if (strcasecmp(buff, hp->Name) == 0) {
+ fp->Header = hp;
+ break;
+ }
+ }
+ if (hp == ARRAY_END(ARTheaders)) {
+ syslog(L_ERROR, "%s bad_schema unknown header \"%s\"",
+ LogName, buff);
+ ok = false;
+ continue;
+ }
+ fp++;
+ }
+ fp->Header = NULL;
+
+ Fclose(F);
+ if (!foundxref || !foundxreffull) {
+ syslog(L_FATAL, "%s 'Xref:full' must be included in %s", LogName, SCHEMA);
+ exit(1);
+ }
+ return ok;
+}
+
+
+/*
+** Build a balanced tree for the headers in subscript range [lo..hi).
+** This only gets called once, and the tree only has about 37 entries,
+** so we don't bother to unroll the recursion.
+*/
+static TREE *
+ARTbuildtree(const ARTHEADER **Table, int lo, int hi)
+{
+ int mid;
+ TREE *tp;
+
+ mid = lo + (hi - lo) / 2;
+ tp = xmalloc(sizeof(TREE));
+ tp->Header = Table[mid];
+ tp->Name = tp->Header->Name;
+ if (mid == lo)
+ tp->Before = NULL;
+ else
+ tp->Before = ARTbuildtree(Table, lo, mid);
+ if (mid == hi - 1)
+ tp->After = NULL;
+ else
+ tp->After = ARTbuildtree(Table, mid + 1, hi);
+ return tp;
+}
+
+
+/*
+** Sorting predicate for qsort call in ARTsetup.
+*/
+static int
+ARTcompare(const void *p1, const void *p2)
+{
+ return strcasecmp(((const ARTHEADER **)p1)[0]->Name,
+ ((const ARTHEADER **)p2)[0]->Name);
+}
+
+
+/*
+** Setup the article processing.
+*/
+void
+ARTsetup(void)
+{
+ const char * p;
+ const ARTHEADER ** table;
+ unsigned int i;
+
+ /* Set up the character class tables. These are written a
+ * little strangely to work around a GCC2.0 bug. */
+ memset(ARTcclass, 0, sizeof ARTcclass);
+ p = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ while ((i = *p++) != 0) {
+ ARTcclass[i] = CC_HOSTNAME | CC_MSGID_ATOM | CC_MSGID_NORM;
+ }
+ p = "!#$%&'*+-/=?^_`{|}~";
+ while ((i = *p++) != 0) {
+ ARTcclass[i] = CC_MSGID_ATOM | CC_MSGID_NORM;
+ }
+ p = "\"(),.:;<@[\\]";
+ while ((i = *p++) != 0) {
+ ARTcclass[i] = CC_MSGID_NORM;
+ }
+
+ /* The RFC's don't require it, but we add underscore to the list of valid
+ * hostname characters. */
+ ARTcclass['.'] |= CC_HOSTNAME;
+ ARTcclass['-'] |= CC_HOSTNAME;
+ ARTcclass['_'] |= CC_HOSTNAME;
+
+ /* Build the header tree. */
+ table = xmalloc(ARRAY_SIZE(ARTheaders) * sizeof(ARTHEADER *));
+ for (i = 0; i < ARRAY_SIZE(ARTheaders); i++)
+ table[i] = &ARTheaders[i];
+ qsort(table, ARRAY_SIZE(ARTheaders), sizeof *table, ARTcompare);
+ ARTheadertree = ARTbuildtree(table, 0, ARRAY_SIZE(ARTheaders));
+ free(table);
+
+ /* Get our Path name, kill trailing !. */
+ ARTpathme = xstrdup(Path.data);
+ ARTpathme[Path.used - 1] = '\0';
+
+ /* Set up database; ignore errors. */
+ ARTreadschema();
+}
+
+
+static void
+ARTfreetree(TREE *tp)
+{
+ TREE *next;
+
+ for ( ; tp != NULL; tp = next) {
+ if (tp->Before)
+ ARTfreetree(tp->Before);
+ next = tp->After;
+ free(tp);
+ }
+}
+
+
+void
+ARTclose(void)
+{
+ if (ARTfields != NULL) {
+ free(ARTfields);
+ ARTfields = NULL;
+ }
+ ARTfreetree(ARTheadertree);
+}
+
+/*
+** Start a log message about an article.
+*/
+static void
+ARTlog(const ARTDATA *data, char code, const char *text)
+{
+ const HDRCONTENT *hc = data->HdrContent;
+ int i;
+ bool Done;
+
+ TMRstart(TMR_ARTLOG);
+ /* We could be a bit faster by not dividing Now.usec by 1000,
+ * but who really wants to log at the Microsec level? */
+ Done = code == ART_ACCEPT || code == ART_JUNK;
+ if (text)
+ i = fprintf(Log, "%.15s.%03d %c %s %s %s%s",
+ ctime(&Now.time) + 4, (int)(Now.usec / 1000), code, data->Feedsite,
+ HDR_FOUND(HDR__MESSAGE_ID) ? HDR(HDR__MESSAGE_ID) : "(null)",
+ text, Done ? "" : "\n");
+ else
+ i = fprintf(Log, "%.15s.%03d %c %s %s%s",
+ ctime(&Now.time) + 4, (int)(Now.usec / 1000), code, data->Feedsite,
+ HDR_FOUND(HDR__MESSAGE_ID) ? HDR(HDR__MESSAGE_ID) : "(null)",
+ Done ? "" : "\n");
+ if (i == EOF || (Done && !BufferedLogs && fflush(Log)) || ferror(Log)) {
+ i = errno;
+ syslog(L_ERROR, "%s cant write log_start %m", LogName);
+ IOError("logging article", i);
+ clearerr(Log);
+ }
+ TMRstop(TMR_ARTLOG);
+}
+
+/*
+** Parse a Path line, splitting it up into NULL-terminated array of strings.
+*/
+static int
+ARTparsepath(const char *p, int size, LISTBUFFER *list)
+{
+ int i;
+ char *q, **hp;
+
+ /* setup buffer */
+ SetupListBuffer(size, list);
+
+ /* loop over text and copy */
+ for (i = 0, q = list->Data, hp = list->List ; *p ; p++, *q++ = '\0') {
+ /* skip leading separators. */
+ for (; *p && !ARThostchar(*p) && ISWHITE(*p) ; p++)
+ continue;
+ if (*p == '\0')
+ break;
+
+ if (list->ListLength <= i) {
+ list->ListLength += DEFAULTNGBOXSIZE;
+ list->List = xrealloc(list->List, list->ListLength * sizeof(char *));
+ hp = &list->List[i];
+ }
+ /* mark the start of the host, move to the end of it while copying */
+ for (*hp++ = q, i++ ; *p && ARThostchar(*p) && !ISWHITE(*p) ;)
+ *q++ = *p++;
+ if (*p == '\0')
+ break;
+ }
+ *q = '\0';
+ if (i == list->ListLength) {
+ list->ListLength += DEFAULTNGBOXSIZE;
+ list->List = xrealloc(list->List, list->ListLength * sizeof(char *));
+ hp = &list->List[i];
+ }
+ *hp = NULL;
+ return i;
+}
+
+/*
+** Sorting pointer where header starts
+*/
+static int
+ARTheaderpcmp(const void *p1, const void *p2)
+{
+ return (((const HEADERP *)p1)->p - ((const HEADERP *)p2)->p);
+}
+
+/* Write an article using the storage api. Put it together in memory and
+ call out to the api. */
+static TOKEN
+ARTstore(CHANNEL *cp)
+{
+ struct buffer *Article = &cp->In;
+ ARTDATA *data = &cp->Data;
+ HDRCONTENT *hc = data->HdrContent;
+ const char *p;
+ ARTHANDLE arth;
+ int i, j, iovcnt = 0;
+ long headersize = 0;
+ TOKEN result;
+ struct buffer *headers = &data->Headers;
+ struct iovec iov[ARTIOVCNT];
+ HEADERP hp[HPCOUNT];
+
+ /* find Path, Bytes and Xref to be prepended/dropped/replaced */
+ arth.len = i = 0;
+ /* assumes Path header is required header */
+ hp[i].p = HDR(HDR__PATH);
+ hp[i++].index = HDR__PATH;
+ if (HDR_FOUND(HDR__XREF)) {
+ hp[i].p = HDR(HDR__XREF);
+ hp[i++].index = HDR__XREF;
+ }
+ if (HDR_FOUND(HDR__BYTES)) {
+ hp[i].p = HDR(HDR__BYTES);
+ hp[i++].index = HDR__BYTES;
+ }
+ /* get the order of header appearance */
+ qsort(hp, i, sizeof(HEADERP), ARTheaderpcmp);
+ /* p always points where the next data should be written from */
+ for (p = Article->data + cp->Start, j = 0 ; j < i ; j++) {
+ switch (hp[j].index) {
+ case HDR__PATH:
+ if (!data->Hassamepath || data->AddAlias || Pathcluster.used) {
+ /* write heading data */
+ iov[iovcnt].iov_base = (char *) p;
+ iov[iovcnt++].iov_len = HDR(HDR__PATH) - p;
+ arth.len += HDR(HDR__PATH) - p;
+ /* append clusterpath */
+ if (Pathcluster.used) {
+ iov[iovcnt].iov_base = Pathcluster.data;
+ iov[iovcnt++].iov_len = Pathcluster.used;
+ arth.len += Pathcluster.used;
+ }
+ /* now append new one */
+ iov[iovcnt].iov_base = Path.data;
+ iov[iovcnt++].iov_len = Path.used;
+ arth.len += Path.used;
+ if (data->AddAlias) {
+ iov[iovcnt].iov_base = Pathalias.data;
+ iov[iovcnt++].iov_len = Pathalias.used;
+ arth.len += Pathalias.used;
+ }
+ /* next to write */
+ p = HDR(HDR__PATH);
+ if (data->Hassamecluster)
+ p += Pathcluster.used;
+ }
+ break;
+ case HDR__XREF:
+ if (!innconf->xrefslave) {
+ /* write heading data */
+ iov[iovcnt].iov_base = (char *) p;
+ iov[iovcnt++].iov_len = HDR(HDR__XREF) - p;
+ arth.len += HDR(HDR__XREF) - p;
+ /* replace with new one */
+ iov[iovcnt].iov_base = data->Xref;
+ iov[iovcnt++].iov_len = data->XrefLength - 2;
+ arth.len += data->XrefLength - 2;
+ /* next to write */
+ /* this points where trailing "\r\n" of orginal Xref header exists */
+ p = HDR(HDR__XREF) + HDR_LEN(HDR__XREF);
+ }
+ break;
+ case HDR__BYTES:
+ /* ditch whole Byte header */
+ /* write heading data */
+ iov[iovcnt].iov_base = (char *) p;
+ iov[iovcnt++].iov_len = data->BytesHeader - p;
+ arth.len += data->BytesHeader - p;
+ /* next to write */
+ /* need to skip trailing "\r\n" of Bytes header */
+ p = HDR(HDR__BYTES) + HDR_LEN(HDR__BYTES) + 2;
+ break;
+ default:
+ result.type = TOKEN_EMPTY;
+ return result;
+ }
+ }
+ /* in case Xref is not included in orignal article */
+ if (!HDR_FOUND(HDR__XREF)) {
+ /* write heading data */
+ iov[iovcnt].iov_base = (char *) p;
+ iov[iovcnt++].iov_len = Article->data + (data->Body - 2) - p;
+ arth.len += Article->data + (data->Body - 2) - p;
+ /* Xref needs to be inserted */
+ iov[iovcnt].iov_base = (char *) "Xref: ";
+ iov[iovcnt++].iov_len = sizeof("Xref: ") - 1;
+ arth.len += sizeof("Xref: ") - 1;
+ iov[iovcnt].iov_base = data->Xref;
+ iov[iovcnt++].iov_len = data->XrefLength;
+ arth.len += data->XrefLength;
+ p = Article->data + (data->Body - 2);
+ }
+ /* write rest of data */
+ iov[iovcnt].iov_base = (char *) p;
+ iov[iovcnt++].iov_len = Article->data + cp->Next - p;
+ arth.len += Article->data + cp->Next - p;
+
+ /* revert trailing '\0\n' to '\r\n' of all system header */
+ for (i = 0 ; i < MAX_ARTHEADER ; i++) {
+ if (HDR_FOUND(i))
+ HDR_PARSE_END(i);
+ }
+
+ arth.iov = iov;
+ arth.iovcnt = iovcnt;
+ arth.arrived = (time_t)0;
+ arth.token = (TOKEN *)NULL;
+ arth.expires = data->Expires;
+ if (innconf->storeonxref) {
+ arth.groups = data->Replic;
+ arth.groupslen = data->ReplicLength;
+ } else {
+ arth.groups = HDR(HDR__NEWSGROUPS);
+ arth.groupslen = HDR_LEN(HDR__NEWSGROUPS);
+ }
+
+ SMerrno = SMERR_NOERROR;
+ result = SMstore(arth);
+ if (result.type == TOKEN_EMPTY) {
+ if (SMerrno == SMERR_NOMATCH)
+ ThrottleNoMatchError();
+ else if (SMerrno != SMERR_NOERROR)
+ IOError("SMstore", SMerrno);
+ return result;
+ }
+
+ /* calculate stored size */
+ for (data->BytesValue = i = 0 ; i < iovcnt ; i++) {
+ if (NeedHeaders && (i + 1 == iovcnt)) {
+ /* body begins at last iov */
+ headersize = data->BytesValue +
+ Article->data + data->Body - (char *) iov[i].iov_base;
+ }
+ data->BytesValue += iov[i].iov_len;
+ }
+ /* "\r\n" is counted as 1 byte. trailing ".\r\n" and body delimitor are also
+ substituted */
+ data->BytesValue -= (data->HeaderLines + data->Lines + 4);
+ /* Figure out how much space we'll need and get it. */
+ snprintf(data->Bytes, sizeof(data->Bytes), "Bytes: %ld\r\n",
+ data->BytesValue);
+ /* does not include strlen("Bytes: \r\n") */
+ data->BytesLength = strlen(data->Bytes) - 9;
+
+ if (!NeedHeaders)
+ return result;
+
+ /* Add the data. */
+ buffer_resize(headers, headersize);
+ buffer_set(headers, data->Bytes, strlen(data->Bytes));
+ for (i = 0 ; i < iovcnt ; i++) {
+ if (i + 1 == iovcnt)
+ buffer_append(headers, iov[i].iov_base,
+ Article->data + data->Body - (char *) iov[i].iov_base);
+ else
+ buffer_append(headers, iov[i].iov_base, iov[i].iov_len);
+ }
+ buffer_trimcr(headers);
+
+ return result;
+}
+
+/*
+** Parse a header that starts at header. size includes trailing "\r\n"
+*/
+static void
+ARTparseheader(CHANNEL *cp, int size)
+{
+ ARTDATA *data = &cp->Data;
+ char *header = cp->In.data + data->CurHeader;
+ HDRCONTENT *hc = cp->Data.HdrContent;
+ TREE *tp;
+ const ARTHEADER *hp;
+ char c, *p, *colon;
+ int i;
+
+ /* Find first colon */
+ if ((colon = memchr(header, ':', size)) == NULL || !ISWHITE(colon[1])) {
+ if ((p = memchr(header, '\r', size)) != NULL)
+ *p = '\0';
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d No colon-space in \"%s\" header",
+ NNTP_REJECTIT_VAL, MaxLength(header, header));
+ if (p != NULL)
+ *p = '\r';
+ return;
+ }
+
+ /* See if this is a system header. A fairly tightly-coded binary search. */
+ c = CTYPE(islower, *header) ? toupper(*header) : *header;
+ for (*colon = '\0', tp = ARTheadertree; tp; ) {
+ if ((i = c - tp->Name[0]) == 0 && (i = strcasecmp(header, tp->Name)) == 0)
+ break;
+ if (i < 0)
+ tp = tp->Before;
+ else
+ tp = tp->After;
+ }
+ *colon = ':';
+
+ if (tp == NULL) {
+ /* Not a system header, make sure we have <word><colon><space>. */
+ for (p = colon; --p > header; ) {
+ if (ISWHITE(*p)) {
+ c = *p;
+ *p = '\0';
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d Space before colon in \"%s\" header",
+ NNTP_REJECTIT_VAL, MaxLength(header, header));
+ *p = c;
+ return;
+ }
+ }
+ return;
+ }
+ hp = tp->Header;
+ i = hp - ARTheaders;
+ /* remember to ditch if it's Bytes: */
+ if (i == HDR__BYTES)
+ cp->Data.BytesHeader = header;
+ hc = &hc[i];
+ if (hc->Length != 0) {
+ /* duplicated */
+ hc->Length = -1;
+ } else {
+ for (p = colon + 1 ; (p < header + size - 2) &&
+ (ISWHITE(*p) || *p == '\r' || *p == '\n'); p++);
+ if (p < header + size - 2) {
+ hc->Value = p;
+ /* HDR_LEN() does not include trailing "\r\n" */
+ hc->Length = header + size - 2 - p;
+ } else {
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d Body of header is all blanks in \"%s\" header",
+ NNTP_REJECTIT_VAL, MaxLength(hp->Name, hp->Name));
+ }
+ }
+ return;
+}
+
+/*
+** Check Message-ID format based on RFC 822 grammar, except that (as per
+** RFC 1036) whitespace, non-printing, and '>' characters are excluded.
+** Based on code by Paul Eggert posted to news.software.b on 22-Nov-90
+** in <#*tyo2'~n@twinsun.com>, with additional email discussion.
+** Thanks, Paul.
+*/
+bool
+ARTidok(const char *MessageID)
+{
+ int c;
+ const char *p;
+
+ /* Check the length of the message ID. */
+ if (MessageID == NULL || strlen(MessageID) > NNTP_MSGID_MAXLEN)
+ return false;
+
+ /* Scan local-part: "< atom|quoted [ . atom|quoted]" */
+ p = MessageID;
+ if (*p++ != '<')
+ return false;
+ for (; ; p++) {
+ if (ARTatomchar(*p))
+ while (ARTatomchar(*++p))
+ continue;
+ else {
+ if (*p++ != '"')
+ return false;
+ for ( ; ; ) {
+ switch (c = *p++) {
+ case '\\':
+ c = *p++;
+ /* FALLTHROUGH */
+ default:
+ if (ARTnormchar(c))
+ continue;
+ return false;
+ case '"':
+ break;
+ }
+ break;
+ }
+ }
+ if (*p != '.')
+ break;
+ }
+
+ /* Scan domain part: "@ atom|domain [ . atom|domain] > \0" */
+ if (*p++ != '@')
+ return false;
+ for ( ; ; p++) {
+ if (ARTatomchar(*p))
+ while (ARTatomchar(*++p))
+ continue;
+ else {
+ if (*p++ != '[')
+ return false;
+ for ( ; ; ) {
+ switch (c = *p++) {
+ case '\\':
+ c = *p++;
+ /* FALLTHROUGH */
+ default:
+ if (ARTnormchar(c))
+ continue;
+ /* FALLTHROUGH */
+ case '[':
+ return false;
+ case ']':
+ break;
+ }
+ break;
+ }
+ }
+ if (*p != '.')
+ break;
+ }
+
+ return *p == '>' && *++p == '\0';
+}
+
+/*
+** Clean up data field where article informations are stored.
+** This must be called before article processing.
+*/
+void
+ARTprepare(CHANNEL *cp)
+{
+ ARTDATA *data = &cp->Data;
+ HDRCONTENT *hc = data->HdrContent;
+ int i;
+
+ for (i = 0 ; i < MAX_ARTHEADER ; i++, hc++) {
+ hc->Value = NULL;
+ hc->Length = 0;
+ }
+ data->Lines = data->HeaderLines = data->CRwithoutLF = data->LFwithoutCR = 0;
+ data->CurHeader = data->LastTerminator = data->LastCR = cp->Start - 1;
+ data->LastCRLF = data->Body = cp->Start - 1;
+ data->BytesHeader = NULL;
+ data->Feedsite = "?";
+ *cp->Error = '\0';
+}
+
+/*
+** Clean up an article. This is mainly copying in-place, stripping bad
+** headers. Also fill in the article data block with what we can find.
+** Return NULL if the article is okay, or a string describing the error.
+** Parse headers and end of article
+** This is called by NCproc().
+*/
+void
+ARTparse(CHANNEL *cp)
+{
+ struct buffer *bp = &cp->In;
+ ARTDATA *data = &cp->Data;
+ long i, limit, fudge, size;
+ int hopcount;
+ char **hops;
+ HDRCONTENT *hc = data->HdrContent;
+
+ /* Read through the buffer to find header, body and end of article */
+ /* this routine is designed not to refer data so long as possible for
+ performance reason, so the code may look redundant at a glance */
+ limit = bp->used;
+ i = cp->Next;
+ if (cp->State == CSgetheader) {
+ /* header processing */
+ for (; i < limit ;) {
+ if (data->LastCRLF + 1 == i) {
+ /* begining of the line */
+ switch (bp->data[i]) {
+ case '.':
+ data->LastTerminator = i;
+ data->NullHeader = false;
+ break;
+ case '\r':
+ data->LastCR = i;
+ data->NullHeader = false;
+ break;
+ case '\n':
+ data->LFwithoutCR++;
+ data->NullHeader = false;
+ break;
+ case '\t':
+ case ' ':
+ /* header is folded. NullHeader is untouched */
+ break;
+ case '\0':
+ snprintf(cp->Error, sizeof(cp->Error), "%d Null Header",
+ NNTP_REJECTIT_VAL);
+ data->NullHeader = true;
+ break;
+ default:
+ if (data->CurHeader >= cp->Start) {
+ /* parse previous header */
+ if (!data->NullHeader && (*cp->Error == '\0'))
+ /* skip if already got an error */
+ ARTparseheader(cp, i - data->CurHeader);
+ }
+ data->CurHeader = i;
+ data->NullHeader = false;
+ break;
+ }
+ i++;
+ }
+ for (; i < limit ;) {
+ /* rest of the line */
+ switch (bp->data[i]) {
+ case '\0':
+ snprintf(cp->Error, sizeof(cp->Error), "%d Null Header",
+ NNTP_REJECTIT_VAL);
+ data->NullHeader = true;
+ break;
+ case '\r':
+ if (data->LastCR >= cp->Start)
+ data->CRwithoutLF++;
+ data->LastCR = i;
+ break;
+ case '\n':
+ if (data->LastCR + 1 == i) {
+ /* found CRLF */
+ data->LastCR = cp->Start - 1;
+ if (data->LastTerminator + 2 == i) {
+ /* terminated still in header */
+ if (cp->Start + 3 == i) {
+ snprintf(cp->Error, sizeof(cp->Error), "%d Empty article",
+ NNTP_REJECTIT_VAL);
+ cp->State = CSnoarticle;
+ } else {
+ snprintf(cp->Error, sizeof(cp->Error), "%d No body",
+ NNTP_REJECTIT_VAL);
+ cp->State = CSgotarticle;
+ }
+ cp->Next = ++i;
+ goto sizecheck;
+ }
+ if (data->LastCRLF + MAXHEADERSIZE < i)
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d Too long line in header %ld bytes",
+ NNTP_REJECTIT_VAL, i - data->LastCRLF);
+ else if (data->LastCRLF + 2 == i) {
+ /* header ends */
+ /* parse previous header */
+ if (data->CurHeader >= cp->Start) {
+ if (!data->NullHeader && (*cp->Error == '\0'))
+ /* skip if already got an error */
+ ARTparseheader(cp, i - 1 - data->CurHeader);
+ } else {
+ snprintf(cp->Error, sizeof(cp->Error), "%d No header",
+ NNTP_REJECTIT_VAL);
+ }
+ data->LastCRLF = i++;
+ data->Body = i;
+ cp->State = CSgetbody;
+ goto bodyprocessing;
+ }
+ data->HeaderLines++;
+ data->LastCRLF = i++;
+ goto endofheaderline;
+ } else {
+ data->LFwithoutCR++;
+ }
+ break;
+ default:
+ break;
+ }
+ i++;
+ }
+endofheaderline:
+ ;
+ }
+ } else {
+bodyprocessing:
+ /* body processing, or eating huge article */
+ for (; i < limit ;) {
+ if (data->LastCRLF + 1 == i) {
+ /* begining of the line */
+ switch (bp->data[i]) {
+ case '.':
+ data->LastTerminator = i;
+ break;
+ case '\r':
+ data->LastCR = i;
+ break;
+ case '\n':
+ data->LFwithoutCR++;
+ break;
+ default:
+ break;
+ }
+ i++;
+ }
+ for (; i < limit ;) {
+ /* rest of the line */
+ switch (bp->data[i]) {
+ case '\r':
+ if (data->LastCR >= cp->Start)
+ data->CRwithoutLF++;
+ data->LastCR = i;
+ break;
+ case '\n':
+ if (data->LastCR + 1 == i) {
+ /* found CRLF */
+ data->LastCR = cp->Start - 1;
+ if (data->LastTerminator + 2 == i) {
+ /* found end of article */
+ if (cp->State == CSeatarticle) {
+ cp->State = CSgotlargearticle;
+ cp->Next = ++i;
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d Article of %ld bytes exceeds local limit of %ld bytes",
+ NNTP_REJECTIT_VAL, (unsigned long) i - cp->Start,
+ innconf->maxartsize);
+ } else {
+ cp->State = CSgotarticle;
+ i++;
+ }
+ if (*cp->Error != '\0' && HDR_FOUND(HDR__MESSAGE_ID)) {
+ HDR_PARSE_START(HDR__MESSAGE_ID);
+ if (HDR_FOUND(HDR__PATH)) {
+ /* to record path into news log */
+ HDR_PARSE_START(HDR__PATH);
+ hopcount = ARTparsepath(HDR(HDR__PATH), HDR_LEN(HDR__PATH),
+ &data->Path);
+ HDR_PARSE_END(HDR__PATH);
+ if (hopcount > 0) {
+ hops = data->Path.List;
+ if (innconf->logipaddr) {
+ data->Feedsite = RChostname(cp);
+ if (data->Feedsite == NULL)
+ data->Feedsite = CHANname(cp);
+ if (strcmp("0.0.0.0", data->Feedsite) == 0 ||
+ data->Feedsite[0] == '\0')
+ data->Feedsite =
+ hops && hops[0] ? hops[0] : CHANname(cp);
+ } else {
+ data->Feedsite =
+ hops && hops[0] ? hops[0] : CHANname(cp);
+ }
+ }
+ }
+ ARTlog(data, ART_REJECT, cp->Error);
+ HDR_PARSE_END(HDR__MESSAGE_ID);
+ }
+ if (cp->State == CSgotlargearticle)
+ return;
+ goto sizecheck;
+ }
+#if 0 /* this may be examined in the future */
+ if (data->LastCRLF + MAXHEADERSIZE < i)
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d Too long line in body %d bytes",
+ NNTP_REJECTIT_VAL, i);
+#endif
+ data->Lines++;
+ data->LastCRLF = i++;
+ goto endofline;
+ } else {
+ data->LFwithoutCR++;
+ }
+ break;
+ default:
+ break;
+ }
+ i++;
+ }
+endofline:
+ ;
+ }
+ }
+sizecheck:
+ size = i - cp->Start;
+ fudge = data->HeaderLines + data->Lines + 4;
+ if (innconf->maxartsize > 0)
+ if (size > fudge && size - fudge > innconf->maxartsize)
+ cp->State = CSeatarticle;
+ cp->Next = i;
+ return;
+}
+
+/*
+** Clean up an article. This is mainly copying in-place, stripping bad
+** headers. Also fill in the article data block with what we can find.
+** Return true if the article has no error, or false which means the error.
+*/
+static bool
+ARTclean(ARTDATA *data, char *buff)
+{
+ HDRCONTENT *hc = data->HdrContent;
+ const ARTHEADER *hp = ARTheaders;
+ int i;
+ char *p;
+ int delta;
+
+ TMRstart(TMR_ARTCLEAN);
+ data->Arrived = Now.time;
+ data->Expires = 0;
+
+ /* replace trailing '\r\n' with '\0\n' of all system header to be handled
+ easily by str*() functions */
+ for (i = 0 ; i < MAX_ARTHEADER ; i++) {
+ if (HDR_FOUND(i))
+ HDR_PARSE_START(i);
+ }
+
+ /* Make sure all the headers we need are there */
+ for (i = 0; i < MAX_ARTHEADER ; i++) {
+ if (hp[i].Type == HTreq) {
+ if (HDR_FOUND(i))
+ continue;
+ if (hc[i].Length < 0) {
+ sprintf(buff, "%d Duplicate \"%s\" header", NNTP_REJECTIT_VAL,
+ hp[1].Name);
+ } else {
+ sprintf(buff, "%d Missing \"%s\" header", NNTP_REJECTIT_VAL,
+ hp[i].Name);
+ }
+ TMRstop(TMR_ARTCLEAN);
+ return false;
+ }
+ }
+
+ /* assumes Message-ID header is required header */
+ if (!ARTidok(HDR(HDR__MESSAGE_ID))) {
+ HDR_LEN(HDR__MESSAGE_ID) = 0;
+ sprintf(buff, "%d Bad \"Message-ID\" header", NNTP_REJECTIT_VAL);
+ TMRstop(TMR_ARTCLEAN);
+ return false;
+ }
+
+ if (innconf->linecountfuzz && HDR_FOUND(HDR__LINES)) {
+ p = HDR(HDR__LINES);
+ i = data->Lines;
+ if ((delta = i - atoi(p)) != 0 && abs(delta) > innconf->linecountfuzz) {
+ sprintf(buff, "%d Linecount %s != %d +- %ld", NNTP_REJECTIT_VAL,
+ MaxLength(p, p), i, innconf->linecountfuzz);
+ TMRstop(TMR_ARTCLEAN);
+ return false;
+ }
+ }
+
+ /* Is article too old? */
+ /* assumes Date header is required header */
+ p = HDR(HDR__DATE);
+ if ((data->Posted = parsedate(p, &Now)) == -1) {
+ sprintf(buff, "%d Bad \"Date\" header -- \"%s\"", NNTP_REJECTIT_VAL,
+ MaxLength(p, p));
+ TMRstop(TMR_ARTCLEAN);
+ return false;
+ }
+ if (innconf->artcutoff) {
+ long cutoff = innconf->artcutoff * 24 * 60 * 60;
+
+ if (data->Posted < Now.time - cutoff) {
+ sprintf(buff, "%d Too old -- \"%s\"", NNTP_REJECTIT_VAL,
+ MaxLength(p, p));
+ TMRstop(TMR_ARTCLEAN);
+ return false;
+ }
+ }
+ if (data->Posted > Now.time + DATE_FUZZ) {
+ sprintf(buff, "%d Article posted in the future -- \"%s\"",
+ NNTP_REJECTIT_VAL, MaxLength(p, p));
+ TMRstop(TMR_ARTCLEAN);
+ return false;
+ }
+ if (HDR_FOUND(HDR__EXPIRES)) {
+ p = HDR(HDR__EXPIRES);
+ data->Expires = parsedate(p, &Now);
+ }
+
+ /* Colon or whitespace in the Newsgroups header? */
+ /* assumes Newsgroups header is required header */
+ if ((data->Groupcount =
+ NGsplit(HDR(HDR__NEWSGROUPS), HDR_LEN(HDR__NEWSGROUPS),
+ &data->Newsgroups)) == 0) {
+ TMRstop(TMR_ARTCLEAN);
+ sprintf(buff, "%d Unwanted character in \"Newsgroups\" header",
+ NNTP_REJECTIT_VAL);
+ return false;
+ }
+
+ /* Fill in other Data fields. */
+ if (HDR_FOUND(HDR__SENDER))
+ data->Poster = HDR(HDR__SENDER);
+ else
+ data->Poster = HDR(HDR__FROM);
+ if (HDR_FOUND(HDR__REPLY_TO))
+ data->Replyto = HDR(HDR__REPLY_TO);
+ else
+ data->Replyto = HDR(HDR__FROM);
+
+ TMRstop(TMR_ARTCLEAN);
+ return true;
+}
+
+/*
+** We are going to reject an article, record the reason and
+** and the article.
+*/
+static void
+ARTreject(Reject_type code, CHANNEL *cp, struct buffer *article UNUSED)
+{
+ /* Remember why the article was rejected (for the status file) */
+
+ switch (code) {
+ case REJECT_DUPLICATE:
+ cp->Duplicate++;
+ cp->DuplicateSize += cp->Next - cp->Start;
+ break;
+ case REJECT_SITE:
+ cp->Unwanted_s++;
+ break;
+ case REJECT_FILTER:
+ cp->Unwanted_f++;
+ break;
+ case REJECT_DISTRIB:
+ cp->Unwanted_d++;
+ break;
+ case REJECT_GROUP:
+ cp->Unwanted_g++;
+ break;
+ case REJECT_UNAPP:
+ cp->Unwanted_u++;
+ break;
+ case REJECT_OTHER:
+ cp->Unwanted_o++;
+ break;
+ default:
+ /* should never be here */
+ syslog(L_NOTICE, "%s unknown reject type received by ARTreject()",
+ LogName);
+ break;
+ }
+ /* error */
+}
+
+/*
+** Verify if a cancel message is valid. If the user posting the cancel
+** matches the user who posted the article, return the list of filenames
+** otherwise return NULL.
+*/
+static bool
+ARTcancelverify(const ARTDATA *data, const char *MessageID, TOKEN *token)
+{
+ const char *p;
+ char *q, *q1;
+ const char *local;
+ char buff[SMBUF];
+ ARTHANDLE *art;
+ bool r;
+
+ if (!HISlookup(History, MessageID, NULL, NULL, NULL, token))
+ return false;
+ if ((art = SMretrieve(*token, RETR_HEAD)) == NULL)
+ return false;
+ local = wire_findheader(art->data, art->len, "Sender");
+ if (local == NULL) {
+ local = wire_findheader(art->data, art->len, "From");
+ if (local == NULL) {
+ SMfreearticle(art);
+ return false;
+ }
+ }
+ for (p = local; p < art->data + art->len; p++) {
+ if (*p == '\r' || *p == '\n')
+ break;
+ }
+ if (p == art->data + art->len) {
+ SMfreearticle(art);
+ return false;
+ }
+ q = xmalloc(p - local + 1);
+ memcpy(q, local, p - local);
+ SMfreearticle(art);
+ q[p - local] = '\0';
+ HeaderCleanFrom(q);
+
+ /* Compare canonical forms. */
+ q1 = xstrdup(data->Poster);
+ HeaderCleanFrom(q1);
+ if (strcmp(q, q1) != 0) {
+ r = false;
+ sprintf(buff, "\"%.50s\" wants to cancel %s by \"%.50s\"",
+ q1, MaxLength(MessageID, MessageID), q);
+ ARTlog(data, ART_REJECT, buff);
+ }
+ else {
+ r = true;
+ }
+ free(q1);
+ free(q);
+ return r;
+}
+
+/*
+** Process a cancel message.
+*/
+void
+ARTcancel(const ARTDATA *data, const char *MessageID, const bool Trusted)
+{
+ char buff[SMBUF+16];
+ TOKEN token;
+ bool r;
+
+ TMRstart(TMR_ARTCNCL);
+ if (!DoCancels && !Trusted) {
+ TMRstop(TMR_ARTCNCL);
+ return;
+ }
+
+ if (!ARTidok(MessageID)) {
+ syslog(L_NOTICE, "%s bad cancel Message-ID %s", data->Feedsite,
+ MaxLength(MessageID, MessageID));
+ TMRstop(TMR_ARTCNCL);
+ return;
+ }
+
+ if (!HIScheck(History, MessageID)) {
+ /* Article hasn't arrived here, so write a fake entry using
+ * most of the information from the cancel message. */
+ if (innconf->verifycancels && !Trusted) {
+ TMRstop(TMR_ARTCNCL);
+ return;
+ }
+ InndHisRemember(MessageID);
+ snprintf(buff, sizeof(buff), "Cancelling %s",
+ MaxLength(MessageID, MessageID));
+ ARTlog(data, ART_CANC, buff);
+ TMRstop(TMR_ARTCNCL);
+ return;
+ }
+ if (Trusted || !innconf->verifycancels)
+ r = HISlookup(History, MessageID, NULL, NULL, NULL, &token);
+ else
+ r = ARTcancelverify(data, MessageID, &token);
+ if (r == false) {
+ TMRstop(TMR_ARTCNCL);
+ return;
+ }
+
+ /* Get stored message and zap them. */
+ if (!SMcancel(token) && SMerrno != SMERR_NOENT && SMerrno != SMERR_UNINIT)
+ syslog(L_ERROR, "%s cant cancel %s (SMerrno %d)", LogName,
+ TokenToText(token), SMerrno);
+ if (innconf->immediatecancel && !SMflushcacheddata(SM_CANCELEDART))
+ syslog(L_ERROR, "%s cant cancel cached %s", LogName, TokenToText(token));
+ snprintf(buff, sizeof(buff), "Cancelling %s",
+ MaxLength(MessageID, MessageID));
+ ARTlog(data, ART_CANC, buff);
+ TMRstop(TMR_ARTCNCL);
+}
+
+/*
+** Process a control message. Cancels are handled here, but any others
+** are passed out to an external program in a specific directory that
+** has the same name as the first word of the control message.
+*/
+static void
+ARTcontrol(ARTDATA *data, char *Control, CHANNEL *cp UNUSED)
+{
+ char *p, c;
+
+ /* See if it's a cancel message. */
+ c = *Control;
+ if (c == 'c' && strncmp(Control, "cancel", 6) == 0) {
+ for (p = &Control[6]; ISWHITE(*p); p++)
+ continue;
+ if (*p && ARTidok(p))
+ ARTcancel(data, p, false);
+ return;
+ }
+}
+
+/*
+** Parse a Distribution line, splitting it up into NULL-terminated array of
+** strings.
+*/
+static void
+ARTparsedist(const char *p, int size, LISTBUFFER *list)
+{
+ int i;
+ char *q, **dp;
+
+ /* setup buffer */
+ SetupListBuffer(size, list);
+
+ /* loop over text and copy */
+ for (i = 0, q = list->Data, dp = list->List ; *p ; p++, *q++ = '\0') {
+ /* skip leading separators. */
+ for (; *p && ((*p == ',') || ISWHITE(*p)) ; p++)
+ continue;
+ if (*p == '\0')
+ break;
+
+ if (list->ListLength <= i) {
+ list->ListLength += DEFAULTNGBOXSIZE;
+ list->List = xrealloc(list->List, list->ListLength * sizeof(char *));
+ dp = &list->List[i];
+ }
+ /* mark the start of the host, move to the end of it while copying */
+ for (*dp++ = q, i++ ; *p && (*p != ',') && !ISWHITE(*p) ;)
+ *q++ = *p++;
+ if (*p == '\0')
+ break;
+ }
+ *q = '\0';
+ if (i == list->ListLength) {
+ list->ListLength += DEFAULTNGBOXSIZE;
+ list->List = xrealloc(list->List, list->ListLength * sizeof(char *));
+ dp = &list->List[i];
+ }
+ *dp = NULL;
+ return;
+}
+
+/*
+** A somewhat similar routine, except that this handles negated entries
+** in the list and is used to check the distribution sub-field.
+*/
+static bool
+DISTwanted(char **list, char *p)
+{
+ char *q;
+ char c;
+ bool sawbang;
+
+ for (sawbang = false, c = *p; (q = *list) != NULL; list++) {
+ if (*q == '!') {
+ sawbang = true;
+ if (c == *++q && strcmp(p, q) == 0)
+ return false;
+ } else if (c == *q && strcmp(p, q) == 0)
+ return true;
+ }
+
+ /* If we saw any !foo's and didn't match, then assume they are all negated
+ distributions and return true, else return false. */
+ return sawbang;
+}
+
+/*
+** See if any of the distributions in the article are wanted by the site.
+*/
+static bool
+DISTwantany(char **site, char **article)
+{
+ for ( ; *article; article++)
+ if (DISTwanted(site, *article))
+ return true;
+ return false;
+}
+
+/*
+** Send the current article to all sites that would get it if the
+** group were created.
+*/
+static void
+ARTsendthegroup(char *name)
+{
+ SITE *sp;
+ int i;
+ NEWSGROUP *ngp;
+
+ for (ngp = NGfind(ARTctl), sp = Sites, i = nSites; --i >= 0; sp++) {
+ if (sp->Name != NULL && SITEwantsgroup(sp, name)) {
+ SITEmark(sp, ngp);
+ }
+ }
+}
+
+/*
+** Check if site doesn't want this group even if it's crossposted
+** to a wanted group.
+*/
+static void
+ARTpoisongroup(char *name)
+{
+ SITE *sp;
+ int i;
+
+ for (sp = Sites, i = nSites; --i >= 0; sp++) {
+ if (sp->Name != NULL && (sp->PoisonEntry || ME.PoisonEntry) &&
+ SITEpoisongroup(sp, name))
+ sp->Poison = true;
+ }
+}
+
+/*
+** Assign article numbers to the article and create the Xref line.
+** If we end up not being able to write the article, we'll get "holes"
+** in the directory and active file.
+*/
+static void
+ARTassignnumbers(ARTDATA *data)
+{
+ char *p, *q;
+ int i, len, linelen, buflen;
+ NEWSGROUP *ngp;
+
+ if (data->XrefBufLength == 0) {
+ data->XrefBufLength = MAXHEADERSIZE * 2 + 1;
+ data->Xref = xmalloc(data->XrefBufLength);
+ strncpy(data->Xref, Path.data, Path.used - 1);
+ }
+ len = Path.used - 1;
+ p = q = data->Xref + len;
+ for (linelen = i = 0; (ngp = GroupPointers[i]) != NULL; i++) {
+ /* If already went to this group (i.e., multiple groups are aliased
+ * into it), then skip it. */
+ if (ngp->PostCount > 0)
+ continue;
+
+ /* Bump the number. */
+ ngp->PostCount++;
+ ngp->Last++;
+ if (!FormatLong(ngp->LastString, (long)ngp->Last, ngp->Lastwidth)) {
+ syslog(L_ERROR, "%s cant update_active %s", LogName, ngp->Name);
+ continue;
+ }
+ ngp->Filenum = ngp->Last;
+ /* len ' ' "news_groupname" ':' "#" "\r\n" */
+ if (len + 1 + ngp->NameLength + 1 + 10 + 2 > data->XrefBufLength) {
+ data->XrefBufLength += MAXHEADERSIZE;
+ data->Xref = xrealloc(data->Xref, data->XrefBufLength);
+ p = data->Xref + len;
+ }
+ if (linelen + 1 + ngp->NameLength + 1 + 10 > MAXHEADERSIZE) {
+ /* line exceeded */
+ sprintf(p, "\r\n %s:%lu", ngp->Name, ngp->Filenum);
+ buflen = strlen(p);
+ linelen = buflen - 2;
+ } else {
+ sprintf(p, " %s:%lu", ngp->Name, ngp->Filenum);
+ buflen = strlen(p);
+ linelen += buflen;
+ }
+ len += buflen;
+ p += buflen;
+ }
+ /* p[0] is replaced with '\r' to be wireformatted when stored. p[1] needs to
+ be '\n' */
+ p[0] = '\r';
+ p[1] = '\n';
+ /* data->XrefLength includes trailing "\r\n" */
+ data->XrefLength = len + 2;
+ data->Replic = q + 1;
+ data->ReplicLength = len - (q + 1 - data->Xref);
+}
+
+/*
+** Parse the data from the xref header and assign the numbers.
+** This involves replacing the GroupPointers entries.
+*/
+static bool
+ARTxrefslave(ARTDATA *data)
+{
+ char *p, *q, *name, *next, c = 0;
+ NEWSGROUP *ngp;
+ int i;
+ bool nogroup = true;
+ HDRCONTENT *hc = data->HdrContent;
+
+ if (!HDR_FOUND(HDR__XREF))
+ return false;
+ /* skip server name */
+ if ((p = strpbrk(HDR(HDR__XREF), " \t\r\n")) == NULL)
+ return false;
+ /* in case Xref is folded */
+ while (*++p == ' ' || *p == '\t' || *p == '\r' || *p == '\n');
+ if (*p == '\0')
+ return false;
+ data->Replic = p;
+ data->ReplicLength = HDR_LEN(HDR__XREF) - (p - HDR(HDR__XREF));
+ for (i = 0; (*p != '\0') && (p < HDR(HDR__XREF) + HDR_LEN(HDR__XREF)) ; p = next) {
+ /* Mark end of this entry and where next one starts. */
+ name = p;
+ if ((q = next = strpbrk(p, " \t\r\n")) != NULL) {
+ c = *q;
+ *q = '\0';
+ while (*++next == ' ' || *next == '\t' || *next == '\r' || *next == '\n');
+ } else {
+ q = NULL;
+ next = "";
+ }
+
+ /* Split into news.group:# */
+ if ((p = strchr(p, ':')) == NULL) {
+ syslog(L_ERROR, "%s bad_format %s", LogName, name);
+ if (q != NULL)
+ *q = c;
+ continue;
+ }
+ *p = '\0';
+ if ((ngp = NGfind(name)) == NULL) {
+ syslog(L_ERROR, "%s bad_newsgroup %s", LogName, name);
+ *p = ':';
+ if (q != NULL)
+ *q = c;
+ continue;
+ }
+ *p = ':';
+ ngp->Filenum = atol(p + 1);
+ if (q != NULL)
+ *q = c;
+
+ /* Update active file if we got a new high-water mark. */
+ if (ngp->Last < ngp->Filenum) {
+ ngp->Last = ngp->Filenum;
+ if (!FormatLong(ngp->LastString, (long)ngp->Last, ngp->Lastwidth)) {
+ syslog(L_ERROR, "%s cant update_active %s", LogName, ngp->Name);
+ continue;
+ }
+ }
+ /* Mark that this group gets the article. */
+ ngp->PostCount++;
+ GroupPointers[i++] = ngp;
+ nogroup = false;
+ }
+ GroupPointers[i] = NULL;
+ if (nogroup)
+ return false;
+ return true;
+}
+
+/*
+** Return true if a list of strings has a specific one. This is a
+** generic routine, but is used for seeing if a host is in the Path line.
+*/
+static bool
+ListHas(const char **list, const char *p)
+{
+ const char *q;
+ char c;
+
+ for (c = *p; (q = *list) != NULL; list++)
+ if (strcasecmp(p, q) == 0)
+ return true;
+ return false;
+}
+
+/*
+** Even though we have already calculated the Message-ID MD5sum,
+** we have to do it again since unfortunately HashMessageID()
+** lowercases the Message-ID first. We also need to remain
+** compatible with Diablo's hashfeed.
+*/
+
+static unsigned int
+HashFeedMD5(char *MessageID, unsigned int offset)
+{
+ static char LastMessageID[128];
+ static char *LastMessageIDPtr;
+ static struct md5_context context;
+ unsigned int ret;
+
+ if (offset > 12)
+ return 0;
+
+ /* Some light caching. */
+ if (MessageID != LastMessageIDPtr ||
+ strcmp(MessageID, LastMessageID) != 0) {
+ md5_init(&context);
+ md5_update(&context, (unsigned char *)MessageID, strlen(MessageID));
+ md5_final(&context);
+ LastMessageIDPtr = MessageID;
+ strncpy(LastMessageID, MessageID, sizeof(LastMessageID) - 1);
+ LastMessageID[sizeof(LastMessageID) - 1] = 0;
+ }
+
+ memcpy(&ret, &context.digest[12 - offset], 4);
+
+ return ntohl(ret);
+}
+
+/*
+** Old-style Diablo (< 5.1) quickhash.
+**
+*/
+static unsigned int
+HashFeedQH(char *MessageID, unsigned int *tmp)
+{
+ unsigned char *p;
+ int n;
+
+ if (*tmp != (unsigned int)-1)
+ return *tmp;
+
+ p = (unsigned char *)MessageID;
+ n = 0;
+ while (*p)
+ n += *p++;
+ *tmp = (unsigned int)n;
+
+ return *tmp;
+}
+
+/*
+** Return true if an element of the HASHFEEDLIST matches
+** the hash of the Message-ID.
+*/
+static bool
+HashFeedMatch(HASHFEEDLIST *hf, char *MessageID)
+{
+ unsigned int qh = (unsigned int)-1;
+ unsigned int h;
+
+ while (hf) {
+ if (hf->type == HASHFEED_MD5)
+ h = HashFeedMD5(MessageID, hf->offset);
+ else if (hf->type == HASHFEED_QH)
+ h = HashFeedQH(MessageID, &qh);
+ else
+ continue;
+ if ((h % hf->mod + 1) >= hf->begin &&
+ (h % hf->mod + 1) <= hf->end)
+ return true;
+ hf = hf->next;
+ }
+
+ return false;
+}
+
+/*
+** Propagate an article to the sites have "expressed an interest."
+*/
+static void
+ARTpropagate(ARTDATA *data, const char **hops, int hopcount, char **list,
+ bool ControlStore, bool OverviewCreated)
+{
+ HDRCONTENT *hc = data->HdrContent;
+ SITE *sp, *funnel;
+ int i, j, Groupcount, Followcount, Crosscount;
+ char *p, *q;
+ struct buffer *bp;
+ bool sendit;
+
+ /* Work out which sites should really get it. */
+ Groupcount = data->Groupcount;
+ Followcount = data->Followcount;
+ Crosscount = Groupcount + Followcount * Followcount;
+ for (sp = Sites, i = nSites; --i >= 0; sp++) {
+ if ((sp->IgnoreControl && ControlStore) ||
+ (sp->NeedOverviewCreation && !OverviewCreated))
+ sp->Sendit = false;
+ if (sp->Seenit || !sp->Sendit)
+ continue;
+ sp->Sendit = false;
+
+ if (sp->Originator) {
+ if (!HDR_FOUND(HDR__XTRACE)) {
+ if (!sp->FeedwithoutOriginator)
+ continue;
+ } else {
+ if ((p = strchr(HDR(HDR__XTRACE), ' ')) != NULL) {
+ *p = '\0';
+ for (j = 0, sendit = false; (q = sp->Originator[j]) != NULL; j++) {
+ if (*q == '@') {
+ if (uwildmat(HDR(HDR__XTRACE), &q[1])) {
+ *p = ' ';
+ sendit = false;
+ break;
+ }
+ } else {
+ if (uwildmat(HDR(HDR__XTRACE), q))
+ sendit = true;
+ }
+ }
+ *p = ' ';
+ if (!sendit)
+ continue;
+ } else
+ continue;
+ }
+ }
+
+ if (sp->Master != NOSITE && Sites[sp->Master].Seenit)
+ continue;
+
+ if (sp->MaxSize && data->BytesValue > sp->MaxSize)
+ /* Too big for the site. */
+ continue;
+
+ if (sp->MinSize && data->BytesValue < sp->MinSize)
+ /* Too small for the site. */
+ continue;
+
+ if ((sp->Hops && hopcount > sp->Hops)
+ || (!sp->IgnorePath && ListHas(hops, sp->Name))
+ || (sp->Groupcount && Groupcount > sp->Groupcount)
+ || (sp->Followcount && Followcount > sp->Followcount)
+ || (sp->Crosscount && Crosscount > sp->Crosscount))
+ /* Site already saw the article; path too long; or too much
+ * cross-posting. */
+ continue;
+
+ if (sp->HashFeedList &&
+ !HashFeedMatch(sp->HashFeedList, HDR(HDR__MESSAGE_ID)))
+ /* hashfeed doesn't match */
+ continue;
+
+ if (list && *list != NULL && sp->Distributions &&
+ !DISTwantany(sp->Distributions, list))
+ /* Not in the site's desired list of distributions. */
+ continue;
+ if (sp->DistRequired && list == NULL)
+ /* Site requires Distribution header and there isn't one. */
+ continue;
+
+ if (sp->Exclusions) {
+ for (j = 0; (p = sp->Exclusions[j]) != NULL; j++)
+ if (ListHas(hops, p))
+ break;
+ if (p != NULL)
+ /* A host in the site's exclusion list was in the Path. */
+ continue;
+ }
+
+ /* Write that the site is getting it, and flag to send it. */
+ if (innconf->logsitename) {
+ if (fprintf(Log, " %s", sp->Name) == EOF || ferror(Log)) {
+ j = errno;
+ syslog(L_ERROR, "%s cant write log_site %m", LogName);
+ IOError("logging site", j);
+ clearerr(Log);
+ }
+ }
+ sp->Sendit = true;
+ sp->Seenit = true;
+ if (sp->Master != NOSITE)
+ Sites[sp->Master].Seenit = true;
+ }
+ if (putc('\n', Log) == EOF
+ || (!BufferedLogs && fflush(Log))
+ || ferror(Log)) {
+ syslog(L_ERROR, "%s cant write log_end %m", LogName);
+ clearerr(Log);
+ }
+
+ /* Handle funnel sites. */
+ for (sp = Sites, i = nSites; --i >= 0; sp++) {
+ if (sp->Sendit && sp->Funnel != NOSITE) {
+ sp->Sendit = false;
+ funnel = &Sites[sp->Funnel];
+ funnel->Sendit = true;
+ if (funnel->FNLwantsnames) {
+ bp = &funnel->FNLnames;
+ p = &bp->data[bp->used];
+ if (bp->used) {
+ *p++ = ' ';
+ bp->used++;
+ }
+ bp->used += strlcpy(p, sp->Name, bp->size - bp->used);
+ }
+ }
+ }
+}
+
+/*
+** Build up the overview data.
+*/
+static void
+ARTmakeoverview(CHANNEL *cp)
+{
+ ARTDATA *data = &cp->Data;
+ HDRCONTENT *hc = data->HdrContent;
+ static char SEP[] = "\t";
+ static char COLONSPACE[] = ": ";
+ struct buffer *overview = &data->Overview;
+ ARTOVERFIELD *fp;
+ const ARTHEADER *hp;
+ char *p, *q;
+ int i, j, len;
+ char *key_old_value = NULL;
+ int key_old_length = 0;
+
+ if (ARTfields == NULL) {
+ /* User error. */
+ return;
+ }
+
+ /* Setup. */
+ buffer_resize(overview, MAXHEADERSIZE);
+ buffer_set(overview, "", 0);
+
+ /* Write the data, a field at a time. */
+ for (fp = ARTfields; fp->Header; fp++) {
+ if (fp != ARTfields)
+ buffer_append(overview, SEP, strlen(SEP));
+ hp = fp->Header;
+ j = hp - ARTheaders;
+
+ /* If requested, generate keywords from the body of the article and patch
+ them into the apparent value of the Keywords header so that they make
+ it into overview. */
+ if (DO_KEYWORDS && innconf->keywords) {
+ /* Ensure that there are Keywords: to shovel. */
+ if (hp == &ARTheaders[HDR__KEYWORDS]) {
+ key_old_value = HDR(HDR__KEYWORDS);
+ key_old_length = HDR_LEN(HDR__KEYWORDS);
+ KEYgenerate(&hc[HDR__KEYWORDS], cp->In.data + data->Body,
+ key_old_value, key_old_length);
+ }
+ }
+
+ switch (j) {
+ case HDR__BYTES:
+ p = data->Bytes + 7; /* skip "Bytes: " */
+ len = data->BytesLength;
+ break;
+ case HDR__XREF:
+ if (innconf->xrefslave) {
+ p = HDR(j);
+ len = HDR_LEN(j);
+ } else {
+ p = data->Xref;
+ len = data->XrefLength - 2;
+ }
+ break;
+ default:
+ p = HDR(j);
+ len = HDR_LEN(j);
+ break;
+ }
+ if (len == 0)
+ continue;
+ if (fp->NeedHeader) {
+ buffer_append(overview, hp->Name, hp->Size);
+ buffer_append(overview, COLONSPACE, strlen(COLONSPACE));
+ }
+ if (overview->used + overview->left + len > overview->size)
+ buffer_resize(overview, overview->size + len);
+ for (i = 0, q = overview->data + overview->left; i < len; p++, i++) {
+ if (*p == '\r' && i < len - 1 && p[1] == '\n') {
+ p++;
+ i++;
+ continue;
+ }
+ if (*p == '\0' || *p == '\t' || *p == '\n' || *p == '\r')
+ *q++ = ' ';
+ else
+ *q++ = *p;
+ overview->left++;
+ }
+
+ /* Patch the old keywords back in. */
+ if (DO_KEYWORDS && innconf->keywords) {
+ if (key_old_value) {
+ if (hc->Value)
+ free(hc->Value); /* malloc'd within */
+ hc->Value = key_old_value;
+ hc->Length = key_old_length;
+ key_old_value = NULL;
+ }
+ }
+ }
+}
+
+/*
+** This routine is the heart of it all. Take a full article, parse it,
+** file or reject it, feed it to the other sites. Return the NNTP
+** message to send back.
+*/
+bool
+ARTpost(CHANNEL *cp)
+{
+ char *p, **groups, ControlWord[SMBUF], **hops, *controlgroup;
+ int i, j, *isp, hopcount, oerrno, canpost;
+ NEWSGROUP *ngp, **ngptr;
+ SITE *sp;
+ ARTDATA *data = &cp->Data;
+ HDRCONTENT *hc = data->HdrContent;
+ bool Approved, Accepted, LikeNewgroup, ToGroup, GroupMissing;
+ bool NoHistoryUpdate, artclean;
+ bool ControlStore = false;
+ bool NonExist = false;
+ bool OverviewCreated = false;
+ bool IsControl = false;
+ bool Filtered = false;
+ struct buffer *article;
+ HASH hash;
+ TOKEN token;
+ char *groupbuff[2];
+#if defined(DO_PERL) || defined(DO_PYTHON)
+ char *filterrc;
+#endif /* defined(DO_PERL) || defined(DO_PYTHON) */
+ OVADDRESULT result;
+
+ /* Preliminary clean-ups. */
+ article = &cp->In;
+ artclean = ARTclean(data, cp->Error);
+
+ /* If we don't have Path or Message-ID, we can't continue. */
+ if (!artclean && (!HDR_FOUND(HDR__PATH) || !HDR_FOUND(HDR__MESSAGE_ID)))
+ return false;
+ hopcount = ARTparsepath(HDR(HDR__PATH), HDR_LEN(HDR__PATH), &data->Path);
+ if (hopcount == 0) {
+ snprintf(cp->Error, sizeof(cp->Error), "%d illegal path element",
+ NNTP_REJECTIT_VAL);
+ return false;
+ }
+ hops = data->Path.List;
+
+ if (innconf->logipaddr) {
+ data->Feedsite = RChostname(cp);
+ if (data->Feedsite == NULL)
+ data->Feedsite = CHANname(cp);
+ if (strcmp("0.0.0.0", data->Feedsite) == 0 || data->Feedsite[0] == '\0')
+ data->Feedsite = hops && hops[0] ? hops[0] : CHANname(cp);
+ } else {
+ data->Feedsite = hops && hops[0] ? hops[0] : CHANname(cp);
+ }
+ data->FeedsiteLength = strlen(data->Feedsite);
+
+ hash = HashMessageID(HDR(HDR__MESSAGE_ID));
+ data->Hash = &hash;
+ if (HIScheck(History, HDR(HDR__MESSAGE_ID))) {
+ snprintf(cp->Error, sizeof(cp->Error), "%d Duplicate", NNTP_REJECTIT_VAL);
+ ARTlog(data, ART_REJECT, cp->Error);
+ ARTreject(REJECT_DUPLICATE, cp, article);
+ return false;
+ }
+ if (!artclean) {
+ ARTlog(data, ART_REJECT, cp->Error);
+ if (innconf->remembertrash && (Mode == OMrunning) &&
+ !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m", LogName,
+ HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_OTHER, cp, article);
+ return false;
+ }
+
+ i = strlen(hops[0]);
+ if (i == Path.used - 1 &&
+ strncmp(Path.data, hops[0], Path.used - 1) == 0)
+ data->Hassamepath = true;
+ else
+ data->Hassamepath = false;
+ if (Pathcluster.data != NULL &&
+ i == Pathcluster.used - 1 &&
+ strncmp(Pathcluster.data, hops[0], Pathcluster.used - 1) == 0)
+ data->Hassamecluster = true;
+ else
+ data->Hassamecluster = false;
+ if (Pathalias.data != NULL &&
+ !ListHas((const char **)hops, (const char *)innconf->pathalias))
+ data->AddAlias = true;
+ else
+ data->AddAlias = false;
+
+ /* And now check the path for unwanted sites -- Andy */
+ for(j = 0 ; ME.Exclusions && ME.Exclusions[j] ; j++) {
+ if (ListHas((const char **)hops, (const char *)ME.Exclusions[j])) {
+ snprintf(cp->Error, sizeof(cp->Error), "%d Unwanted site %s in path",
+ NNTP_REJECTIT_VAL, MaxLength(ME.Exclusions[j], ME.Exclusions[j]));
+ ARTlog(data, ART_REJECT, cp->Error);
+ if (innconf->remembertrash && (Mode == OMrunning) &&
+ !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m", LogName,
+ HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_SITE, cp, article);
+ return false;
+ }
+ }
+
+#if defined(DO_PERL) || defined(DO_PYTHON)
+ filterPath = HDR(HDR__PATH);
+#endif /* DO_PERL || DO_PYHTON */
+
+#if defined(DO_PYTHON)
+ TMRstart(TMR_PYTHON);
+ filterrc = PYartfilter(data, article->data + data->Body,
+ cp->Next - data->Body, data->Lines);
+ TMRstop(TMR_PYTHON);
+ if (filterrc != NULL) {
+ if (innconf->dontrejectfiltered) {
+ Filtered = true;
+ } else {
+ snprintf(cp->Error, sizeof(cp->Error), "%d %.200s", NNTP_REJECTIT_VAL,
+ filterrc);
+ syslog(L_NOTICE, "rejecting[python] %s %s", HDR(HDR__MESSAGE_ID),
+ cp->Error);
+ ARTlog(data, ART_REJECT, cp->Error);
+ if (innconf->remembertrash && (Mode == OMrunning) &&
+ !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m", LogName,
+ HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_FILTER, cp, article);
+ return false;
+ }
+ }
+#endif /* DO_PYTHON */
+
+ /* I suppose some masochist will run with Python and Perl in together */
+
+#if defined(DO_PERL)
+ TMRstart(TMR_PERL);
+ filterrc = PLartfilter(data, article->data + data->Body,
+ cp->Next - data->Body, data->Lines);
+ TMRstop(TMR_PERL);
+ if (filterrc) {
+ if (innconf->dontrejectfiltered) {
+ Filtered = true;
+ } else {
+ snprintf(cp->Error, sizeof(cp->Error), "%d %.200s", NNTP_REJECTIT_VAL,
+ filterrc);
+ syslog(L_NOTICE, "rejecting[perl] %s %s", HDR(HDR__MESSAGE_ID),
+ cp->Error);
+ ARTlog(data, ART_REJECT, cp->Error);
+ if (innconf->remembertrash && (Mode == OMrunning) &&
+ !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m", LogName,
+ HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_FILTER, cp, article);
+ return false;
+ }
+ }
+#endif /* DO_PERL */
+
+ /* I suppose some masochist will run with both TCL and Perl in together */
+
+#if defined(DO_TCL)
+ if (TCLFilterActive) {
+ int code;
+ const ARTHEADER *hp;
+
+ /* make info available to Tcl */
+
+ TCLCurrArticle = article;
+ TCLCurrData = data;
+ Tcl_UnsetVar(TCLInterpreter, "Body", TCL_GLOBAL_ONLY);
+ Tcl_UnsetVar(TCLInterpreter, "Headers", TCL_GLOBAL_ONLY);
+ for (i = 0 ; i < MAX_ARTHEADER ; i++, hc++) {
+ if (HDR_FOUND(i)) {
+ hp = &ARTheaders[i];
+ Tcl_SetVar2(TCLInterpreter, "Headers", (char *) hp->Name, HDR(i),
+ TCL_GLOBAL_ONLY);
+ }
+ }
+ Tcl_SetVar(TCLInterpreter, "Body", article->data + data->Body,
+ TCL_GLOBAL_ONLY);
+ /* call filter */
+
+ code = Tcl_Eval(TCLInterpreter, "filter_news");
+ Tcl_UnsetVar(TCLInterpreter, "Body", TCL_GLOBAL_ONLY);
+ Tcl_UnsetVar(TCLInterpreter, "Headers", TCL_GLOBAL_ONLY);
+ if (code == TCL_OK) {
+ if (strcmp(TCLInterpreter->result, "accept") != 0) {
+ if (innconf->dontrejectfiltered) {
+ Filtered = true;
+ } else {
+ snprintf(cp->Error, sizeof(cp->Error), "%d %.200s",
+ NNTP_REJECTIT_VAL, TCLInterpreter->result);
+ syslog(L_NOTICE, "rejecting[tcl] %s %s", HDR(HDR__MESSAGE_ID),
+ cp->Error);
+ ARTlog(data, ART_REJECT, cp->Error);
+ if (innconf->remembertrash && (Mode == OMrunning) &&
+ !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m",
+ LogName, HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_FILTER, cp, article);
+ return false;
+ }
+ }
+ } else {
+ /* the filter failed: complain and then turn off filtering */
+ syslog(L_ERROR, "TCL proc filter_news failed: %s",
+ TCLInterpreter->result);
+ TCLfilter(false);
+ }
+ }
+#endif /* defined(DO_TCL) */
+
+ /* If we limit what distributions we get, see if we want this one. */
+ if (HDR_FOUND(HDR__DISTRIBUTION)) {
+ if (HDR(HDR__DISTRIBUTION)[0] == ',') {
+ snprintf(cp->Error, sizeof(cp->Error), "%d bogus distribution \"%s\"",
+ NNTP_REJECTIT_VAL,
+ MaxLength(HDR(HDR__DISTRIBUTION), HDR(HDR__DISTRIBUTION)));
+ ARTlog(data, ART_REJECT, cp->Error);
+ if (innconf->remembertrash && Mode == OMrunning &&
+ !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m", LogName,
+ HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_DISTRIB, cp, article);
+ return false;
+ } else {
+ ARTparsedist(HDR(HDR__DISTRIBUTION), HDR_LEN(HDR__DISTRIBUTION),
+ &data->Distribution);
+ if (ME.Distributions &&
+ !DISTwantany(ME.Distributions, data->Distribution.List)) {
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d Unwanted distribution \"%s\"", NNTP_REJECTIT_VAL,
+ MaxLength(data->Distribution.List[0],
+ data->Distribution.List[0]));
+ ARTlog(data, ART_REJECT, cp->Error);
+ if (innconf->remembertrash && (Mode == OMrunning) &&
+ !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m",
+ LogName, HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_DISTRIB, cp, article);
+ return false;
+ }
+ }
+ } else {
+ ARTparsedist("", 0, &data->Distribution);
+ }
+
+ for (i = nSites, sp = Sites; --i >= 0; sp++) {
+ sp->Poison = false;
+ sp->Sendit = false;
+ sp->Seenit = false;
+ sp->FNLnames.used = 0;
+ sp->ng = NULL;
+ }
+
+ if (HDR_FOUND(HDR__FOLLOWUPTO)) {
+ for (i = 0, p = HDR(HDR__FOLLOWUPTO) ; (p = strchr(p, ',')) != NULL ;
+ i++, p++)
+ continue;
+ data->Followcount = i;
+ }
+ if (data->Followcount == 0)
+ data->Followcount = data->Groupcount;
+
+ groups = data->Newsgroups.List;
+ /* Parse the Control header. */
+ LikeNewgroup = false;
+ if (HDR_FOUND(HDR__CONTROL)) {
+ IsControl = true;
+
+ /* Nip off the first word into lowercase. */
+ strlcpy(ControlWord, HDR(HDR__CONTROL), sizeof(ControlWord));
+ for (p = ControlWord; *p && !ISWHITE(*p); p++)
+ if (CTYPE(isupper, *p))
+ *p = tolower(*p);
+ *p = '\0';
+ LikeNewgroup = (strcmp(ControlWord, "newgroup") == 0
+ || strcmp(ControlWord, "rmgroup") == 0);
+
+ if (innconf->ignorenewsgroups && LikeNewgroup) {
+ for (p++; *p && ISWHITE(*p); p++);
+ groupbuff[0] = p;
+ for (p++; *p; p++) {
+ if (NG_ISSEP(*p)) {
+ *p = '\0';
+ break;
+ }
+ }
+ p = groupbuff[0];
+ for (p++; *p; p++) {
+ if (ISWHITE(*p)) {
+ *p = '\0';
+ break;
+ }
+ }
+ groupbuff[1] = NULL;
+ groups = groupbuff;
+ data->Groupcount = 2;
+ if (data->Followcount == 0)
+ data->Followcount = data->Groupcount;
+ }
+
+ LikeNewgroup = (LikeNewgroup || strcmp(ControlWord, "checkgroups") == 0);
+
+ /* Control messages to "foo.ctl" are treated as if they were
+ * posted to "foo". I should probably apologize for all the
+ * side-effects in the if. */
+ for (i = 0; (p = groups[i++]) != NULL; )
+ if ((j = strlen(p) - 4) > 0 && *(p += j) == '.'
+ && p[1] == 'c' && p[2] == 't' && p[3] == 'l')
+ *p = '\0';
+ }
+
+ /* Loop over the newsgroups, see which ones we want, and get the
+ * total space needed for the Xref line. At the end of this section
+ * of code, j will have the needed length, the appropriate site
+ * entries will have their Sendit and ng fields set, and GroupPointers
+ * will have pointers to the relevant newsgroups. */
+ ToGroup = NoHistoryUpdate = false;
+ Approved = HDR_FOUND(HDR__APPROVED);
+ ngptr = GroupPointers;
+ for (GroupMissing = Accepted = false; (p = *groups) != NULL; groups++) {
+ if ((ngp = NGfind(p)) == NULL) {
+ GroupMissing = true;
+ if (LikeNewgroup && Approved) {
+ /* Checkgroups/newgroup/rmgroup being sent to a group that doesn't
+ * exist. Assume it is being sent to the group being created or
+ * removed (or to the admin group to which the checkgroups is posted),
+ * and send it to all sites that would or would have had the group
+ * if it were created. */
+ ARTsendthegroup(*groups);
+ Accepted = true;
+ } else
+ NonExist = true;
+ ARTpoisongroup(*groups);
+
+ if (innconf->mergetogroups) {
+ /* Try to collapse all "to" newsgroups. */
+ if (*p != 't' || *++p != 'o' || *++p != '.' || *++p == '\0')
+ continue;
+ ngp = NGfind("to");
+ ToGroup = true;
+ if ((sp = SITEfind(p)) != NULL) {
+ SITEmark(sp, ngp);
+ }
+ } else {
+ continue;
+ }
+ }
+
+ ngp->PostCount = 0;
+ /* Ignore this group? */
+ if (ngp->Rest[0] == NF_FLAG_IGNORE) {
+ /* See if any of this group's sites considers this group poison. */
+ for (isp = ngp->Poison, i = ngp->nPoison; --i >= 0; isp++)
+ if (*isp >= 0)
+ Sites[*isp].Poison = true;
+ continue;
+ }
+
+ /* Basic validity check. */
+ if (ngp->Rest[0] == NF_FLAG_MODERATED && !Approved) {
+ snprintf(cp->Error, sizeof(cp->Error), "%d Unapproved for \"%s\"",
+ NNTP_REJECTIT_VAL, MaxLength(ngp->Name, ngp->Name));
+ ARTlog(data, ART_REJECT, cp->Error);
+ if (innconf->remembertrash && (Mode == OMrunning) &&
+ !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m", LogName,
+ HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_UNAPP, cp, article);
+ return false;
+ }
+
+ /* See if any of this group's sites considers this group poison. */
+ for (isp = ngp->Poison, i = ngp->nPoison; --i >= 0; isp++)
+ if (*isp >= 0)
+ Sites[*isp].Poison = true;
+
+ /* Check if we accept articles in this group from this peer, after
+ poisoning. This means that articles that we accept from them will
+ be handled correctly if they're crossposted. */
+ canpost = RCcanpost(cp, p);
+ if (!canpost) { /* At least one group cannot be fed by this peer.
+ If we later reject the post as unwanted group,
+ don't remember it. If we accept, do remember */
+ NoHistoryUpdate = true;
+ continue;
+ } else if (canpost < 0) {
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d Won't accept posts in \"%s\"", NNTP_REJECTIT_VAL,
+ MaxLength(p, p));
+ ARTlog(data, ART_REJECT, cp->Error);
+ ARTreject(REJECT_GROUP, cp, article);
+ return false;
+ }
+
+ /* Valid group, feed it to that group's sites. */
+ Accepted = true;
+ for (isp = ngp->Sites, i = ngp->nSites; --i >= 0; isp++) {
+ if (*isp >= 0) {
+ sp = &Sites[*isp];
+ if (!sp->Poison)
+ SITEmark(sp, ngp);
+ }
+ }
+
+ /* If it's excluded, don't file it. */
+ if (ngp->Rest[0] == NF_FLAG_EXCLUDED)
+ continue;
+
+ /* Expand aliases, mark the article as getting filed in the group. */
+ if (ngp->Alias != NULL)
+ ngp = ngp->Alias;
+ *ngptr++ = ngp;
+ ngp->PostCount = 0;
+ }
+
+ /* Loop over sites to find Poisons/ControlOnly and undo Sendit flags. */
+ for (i = nSites, sp = Sites; --i >= 0; sp++) {
+ if (sp->Poison || (sp->ControlOnly && !IsControl)
+ || (sp->DontWantNonExist && NonExist))
+ sp->Sendit = false;
+ }
+
+ /* Control messages not filed in "to" get filed only in control.name
+ * or control. */
+ if (IsControl && Accepted && !ToGroup) {
+ ControlStore = true;
+ controlgroup = concat("control.", ControlWord, (char *) 0);
+ if ((ngp = NGfind(controlgroup)) == NULL)
+ ngp = NGfind(ARTctl);
+ free(controlgroup);
+ ngp->PostCount = 0;
+ ngptr = GroupPointers;
+ *ngptr++ = ngp;
+ for (isp = ngp->Sites, i = ngp->nSites; --i >= 0; isp++) {
+ if (*isp >= 0) {
+ /* Checkgroups/newgroup/rmgroup posted to local.example
+ * will still be sent with the newsfeeds patterns
+ * "*,!local.*" and "*,@local.*". So as not to propagate
+ * them, "!control,!control.*" should be added. */
+ sp = &Sites[*isp];
+ SITEmark(sp, ngp);
+ }
+ }
+ }
+
+ /* If !Accepted, then none of the article's newgroups exist in our
+ * active file. Proper action is to drop the article on the floor.
+ * If ngp == GroupPointers, then all the new articles newsgroups are
+ * "j" entries in the active file. In that case, we have to file it
+ * under junk so that downstream feeds can get it. */
+ if (!Accepted || ngptr == GroupPointers) {
+ if (!Accepted) {
+ if (NoHistoryUpdate) {
+ snprintf(cp->Error, sizeof(cp->Error), "%d Can't post to \"%s\"",
+ NNTP_REJECTIT_VAL, MaxLength(data->Newsgroups.List[0],
+ data->Newsgroups.List[0]));
+ } else {
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d Unwanted newsgroup \"%s\"", NNTP_REJECTIT_VAL,
+ MaxLength(data->Newsgroups.List[0],
+ data->Newsgroups.List[0]));
+ }
+ ARTlog(data, ART_REJECT, cp->Error);
+ if (!innconf->wanttrash) {
+ if (innconf->remembertrash && (Mode == OMrunning) &&
+ !NoHistoryUpdate && !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m",
+ LogName, HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_GROUP, cp, article);
+ return false;
+ } else {
+ /* if !GroupMissing, then all the groups the article was posted
+ * to have a flag of "x" in our active file, and therefore
+ * we should throw the article away: if you have set
+ * innconf->remembertrash true, then you want all trash except that
+ * which you explicitly excluded in your active file. */
+ if (!GroupMissing) {
+ if (innconf->remembertrash && (Mode == OMrunning) &&
+ !NoHistoryUpdate && !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m",
+ LogName, HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_GROUP, cp, article);
+ return false;
+ }
+ }
+ }
+ ngp = NGfind(ARTjnk);
+ *ngptr++ = ngp;
+ ngp->PostCount = 0;
+
+ /* Junk can be fed to other sites. */
+ for (isp = ngp->Sites, i = ngp->nSites; --i >= 0; isp++) {
+ if (*isp >= 0) {
+ sp = &Sites[*isp];
+ if (!sp->Poison && !(sp->ControlOnly && !IsControl))
+ SITEmark(sp, ngp);
+ }
+ }
+ }
+ *ngptr = NULL;
+
+ if (innconf->xrefslave) {
+ if (ARTxrefslave(data) == false) {
+ if (HDR_FOUND(HDR__XREF)) {
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d Xref header \"%s\" invalid in xrefslave mode",
+ NNTP_REJECTIT_VAL,
+ MaxLength(HDR(HDR__XREF), HDR(HDR__XREF)));
+ } else {
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d Xref header required in xrefslave mode",
+ NNTP_REJECTIT_VAL);
+ }
+ ARTlog(data, ART_REJECT, cp->Error);
+ ARTreject(REJECT_OTHER, cp, article);
+ return false;
+ }
+ } else {
+ ARTassignnumbers(data);
+ }
+
+ /* Now we can file it. */
+ if (++ICDactivedirty >= innconf->icdsynccount) {
+ ICDwriteactive();
+ ICDactivedirty = 0;
+ }
+ TMRstart(TMR_ARTWRITE);
+ for (i = 0; (ngp = GroupPointers[i]) != NULL; i++)
+ ngp->PostCount = 0;
+
+ token = ARTstore(cp);
+ /* change trailing '\r\n' to '\0\n' of all system header */
+ for (i = 0 ; i < MAX_ARTHEADER ; i++) {
+ if (HDR_FOUND(i))
+ HDR_PARSE_START(i);
+ }
+ if (token.type == TOKEN_EMPTY) {
+ syslog(L_ERROR, "%s cant store article: %s", LogName, SMerrorstr);
+ snprintf(cp->Error, sizeof(cp->Error), "%d cant store article",
+ NNTP_RESENDIT_VAL);
+ ARTlog(data, ART_REJECT, cp->Error);
+ if ((Mode == OMrunning) && !InndHisRemember(HDR(HDR__MESSAGE_ID)))
+ syslog(L_ERROR, "%s cant write history %s %m", LogName,
+ HDR(HDR__MESSAGE_ID));
+ ARTreject(REJECT_OTHER, cp, article);
+ TMRstop(TMR_ARTWRITE);
+ return false;
+ }
+ TMRstop(TMR_ARTWRITE);
+ if ((innconf->enableoverview && !innconf->useoverchan) || NeedOverview) {
+ TMRstart(TMR_OVERV);
+ ARTmakeoverview(cp);
+ if (innconf->enableoverview && !innconf->useoverchan) {
+ if ((result = OVadd(token, data->Overview.data, data->Overview.left,
+ data->Arrived, data->Expires)) == OVADDFAILED) {
+ if (OVctl(OVSPACE, (void *)&i) && i == OV_NOSPACE)
+ IOError("creating overview", ENOSPC);
+ else
+ IOError("creating overview", 0);
+ syslog(L_ERROR, "%s cant store overview for %s", LogName,
+ TokenToText(token));
+ OverviewCreated = false;
+ } else {
+ if (result == OVADDCOMPLETED)
+ OverviewCreated = true;
+ else
+ OverviewCreated = false;
+ }
+ }
+ TMRstop(TMR_OVERV);
+ }
+ strlcpy(data->TokenText, TokenToText(token), sizeof(data->TokenText));
+
+ /* Update history if we didn't get too many I/O errors above. */
+ if ((Mode != OMrunning) ||
+ !InndHisWrite(HDR(HDR__MESSAGE_ID), data->Arrived, data->Posted,
+ data->Expires, &token)) {
+ i = errno;
+ syslog(L_ERROR, "%s cant write history %s %m", LogName,
+ HDR(HDR__MESSAGE_ID));
+ snprintf(cp->Error, sizeof(cp->Error), "%d cant write history, %s",
+ NNTP_RESENDIT_VAL, strerror(errno));
+ ARTlog(data, ART_REJECT, cp->Error);
+ ARTreject(REJECT_OTHER, cp, article);
+ return false;
+ }
+
+ if (NeedStoredGroup)
+ data->StoredGroupLength = strlen(data->Newsgroups.List[0]);
+
+ /* Start logging, then propagate the article. */
+ if (data->CRwithoutLF > 0 || data->LFwithoutCR > 0) {
+ if (data->CRwithoutLF > 0 && data->LFwithoutCR == 0)
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d article includes CR without LF(%d)",
+ NNTP_REJECTIT_VAL, data->CRwithoutLF);
+ else if (data->CRwithoutLF == 0 && data->LFwithoutCR > 0)
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d article includes LF without CR(%d)",
+ NNTP_REJECTIT_VAL, data->LFwithoutCR);
+ else
+ snprintf(cp->Error, sizeof(cp->Error),
+ "%d article includes CR without LF(%d) and LF withtout CR(%d)",
+ NNTP_REJECTIT_VAL, data->CRwithoutLF, data->LFwithoutCR);
+ ARTlog(data, ART_STRSTR, cp->Error);
+ }
+ ARTlog(data, Accepted ? ART_ACCEPT : ART_JUNK, (char *)NULL);
+ if ((innconf->nntplinklog) &&
+ (fprintf(Log, " (%s)", data->TokenText) == EOF || ferror(Log))) {
+ oerrno = errno;
+ syslog(L_ERROR, "%s cant write log_nntplink %m", LogName);
+ IOError("logging nntplink", oerrno);
+ clearerr(Log);
+ }
+ /* Calculate Max Article Time */
+ i = Now.time - cp->ArtBeg;
+ if(i > cp->ArtMax)
+ cp->ArtMax = i;
+ cp->ArtBeg = 0;
+
+ cp->Size += data->BytesValue;
+ if (innconf->logartsize) {
+ if (fprintf(Log, " %ld", data->BytesValue) == EOF || ferror (Log)) {
+ oerrno = errno;
+ syslog(L_ERROR, "%s cant write artsize %m", LogName);
+ IOError("logging artsize", oerrno);
+ clearerr(Log);
+ }
+ }
+
+ ARTpropagate(data, (const char **)hops, hopcount, data->Distribution.List,
+ ControlStore, OverviewCreated);
+
+ /* Now that it's been written, process the control message. This has
+ * a small window, if we get a new article before the newgroup message
+ * has been processed. We could pause ourselves here, but it doesn't
+ * seem to be worth it. */
+ if (Accepted) {
+ if (IsControl) {
+ ARTcontrol(data, HDR(HDR__CONTROL), cp);
+ }
+ if (DoCancels && HDR_FOUND(HDR__SUPERSEDES)) {
+ if (ARTidok(HDR(HDR__SUPERSEDES)))
+ ARTcancel(data, HDR(HDR__SUPERSEDES), false);
+ }
+ }
+
+ /* And finally, send to everyone who should get it */
+ for (sp = Sites, i = nSites; --i >= 0; sp++) {
+ if (sp->Sendit) {
+ if (!Filtered || !sp->DropFiltered) {
+ TMRstart(TMR_SITESEND);
+ SITEsend(sp, data);
+ TMRstop(TMR_SITESEND);
+ }
+ }
+ }
+
+ return true;
+}
--- /dev/null
+
+#ifndef PPPORT_H
+#define PPPORT_H 1
+
+/* Perl/Pollution/Portability Version 1.0003 */
+
+/* Copyright (C) 1999, Kenneth Albanowski. This code may be used and
+ distributed under the same license as any version of Perl. */
+
+/* For the latest version of this code, please contact the author at
+ <kjahds@kjahds.com>, or check with the Perl maintainers. */
+
+/* If you needed to customize this file for your project, please mention
+ your changes. */
+
+/*
+ Modified for Perl 5.6.0 by Russ Allbery (use PERL_VERSION instead of
+ PERL_PATCHLEVEL).
+*/
+
+
+/*
+ In order for a Perl extension module to be as portable as possible
+ across differing versions of Perl itself, certain steps need to be taken.
+ Including this header is the first major one, then using dTHR is all the
+ appropriate places and using a PL_ prefix to refer to global Perl
+ variables is the second.
+*/
+
+
+/* If you use one of a few functions that were not present in earlier
+ versions of Perl, please add a define before the inclusion of ppport.h
+ for a static include, or use the GLOBAL request in a single module to
+ produce a global definition that can be referenced from the other
+ modules.
+
+ Function: Static define: Extern define:
+ newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL
+
+*/
+
+
+/* To verify whether ppport.h is needed for your module, and whether any
+ special defines should be used, ppport.h can be run through Perl to check
+ your source code. Simply say:
+
+ perl -x ppport.h *.c *.h *.xs foo/perl.c [etc]
+
+ The result will be a list of patches suggesting changes that should at
+ least be acceptable, if not necessarily the most efficient solution, or a
+ fix for all possible problems. It won't catch where dTHR is needed, and
+ doesn't attempt to account for global macro or function definitions,
+ nested includes, typemaps, etc.
+
+ In order to test for the need of dTHR, please try your module under a
+ recent version of Perl that has threading compiled-in.
+
+*/
+
+
+/*
+#!/usr/bin/perl
+@ARGV = ("*.xs") if !@ARGV;
+%badmacros = %funcs = %macros = ();
+foreach (<DATA>) {
+ $funcs{$1} = 1 if /Provide:\s+(\S+)/;
+ $macros{$1} = 1 if /^#\s*define\s+([a-zA-Z0-9_]+)/;
+ $badmacros{$2}=$1 if /^#\s*define\s+(PL_\S+)\s+(\S+)/;
+}
+foreach $filename (map(glob($_),@ARGV)) {
+ unless (open(IN, "<$filename")) {
+ warn "Unable to read from $file: $!\n";
+ next;
+ }
+ print "Scanning $filename...\n";
+ $c = ""; while (<IN>) { $c .= $_; } close(IN);
+ $need_include = 0; %add_func = (); $changes = 0;
+ $has_include = ($c =~ /#.*include.*ppport/m);
+
+ foreach $func (keys %funcs) {
+ if ($c =~ /#.*define.*\bNEED_$func(_GLOBAL)?\b/m) {
+ if ($c !~ /\b$func\b/m) {
+ print "If $func isn't needed, you don't need to request it.\n" if
+ $changes += ($c =~ s/^.*#.*define.*\bNEED_$func\b.*\n//m);
+ } else {
+ print "Uses $func\n";
+ $need_include = 1;
+ }
+ } else {
+ if ($c =~ /\b$func\b/m) {
+ $add_func{$func} =1 ;
+ print "Uses $func\n";
+ $need_include = 1;
+ }
+ }
+ }
+
+ if (not $need_include) {
+ foreach $macro (keys %macros) {
+ if ($c =~ /\b$macro\b/m) {
+ print "Uses $macro\n";
+ $need_include = 1;
+ }
+ }
+ }
+
+ foreach $badmacro (keys %badmacros) {
+ if ($c =~ /\b$badmacro\b/m) {
+ $changes += ($c =~ s/\b$badmacro\b/$badmacros{$badmacro}/gm);
+ print "Uses $badmacros{$badmacro} (instead of $badmacro)\n";
+ $need_include = 1;
+ }
+ }
+
+ if (scalar(keys %add_func) or $need_include != $has_include) {
+ if (!$has_include) {
+ $inc = join('',map("#define NEED_$_\n", sort keys %add_func)).
+ "#include \"ppport.h\"\n";
+ $c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m;
+ } elsif (keys %add_func) {
+ $inc = join('',map("#define NEED_$_\n", sort keys %add_func));
+ $c = "$inc$c" unless $c =~ s/^.*#.*include.*ppport.*$/$inc$&/m;
+ }
+ if (!$need_include) {
+ print "Doesn't seem to need ppport.h.\n";
+ $c =~ s/^.*#.*include.*ppport.*\n//m;
+ }
+ $changes++;
+ }
+
+ if ($changes) {
+ open(OUT,">/tmp/ppport.h.$$");
+ print OUT $c;
+ close(OUT);
+ open(DIFF, "diff -u $filename /tmp/ppport.h.$$|");
+ while (<DIFF>) { s!/tmp/ppport\.h\.$$!$filename.patched!; print STDOUT; }
+ close(DIFF);
+ unlink("/tmp/ppport.h.$$");
+ } else {
+ print "Looks OK\n";
+ }
+}
+__DATA__
+*/
+
+
+#if !defined(PERL_VERSION) && !defined(PERL_PATCHLEVEL)
+# ifndef __PATCHLEVEL_H_INCLUDED__
+# include <patchlevel.h>
+# endif
+#endif
+#ifndef PERL_VERSION
+# ifdef PERL_PATCHLEVEL
+# define PERL_VERSION PERL_PATCHLEVEL
+# else
+# define PERL_VERSION PATCHLEVEL
+# define PERL_SUBVERSION SUBVERSION
+# endif
+#endif
+
+#ifndef ERRSV
+# define ERRSV perl_get_sv("@",false)
+#endif
+
+#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 4))
+# define PL_sv_undef sv_undef
+# define PL_sv_yes sv_yes
+# define PL_sv_no sv_no
+# define PL_na na
+# define PL_stdingv stdingv
+# define PL_hints hints
+# define PL_curcop curcop
+# define PL_curstash curstash
+# define PL_copline copline
+#endif
+
+#if (PERL_VERSION < 5)
+# undef dTHR
+# ifdef WIN32
+# define dTHR extern int Perl___notused
+# else
+# define dTHR extern int errno
+# endif
+#endif
+
+#ifndef boolSV
+# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
+#endif
+
+/* Perl tries to export a bunch of its own functions. Mutter. */
+#undef die
+#undef list
+#undef warn
+
+#endif /* !PPPORT_H */
--- /dev/null
+/* $Id: perl.c 7815 2008-05-05 08:43:58Z iulius $
+**
+** Perl filtering support for innd.
+**
+** Originally written by Christophe Wolfhugel <wolf@pasteur.fr> (although
+** he wouldn't recognise it anymore so don't blame him) and modified,
+** expanded and tweaked since by James Brister, Jeremy Nixon, Ed Mooring,
+** Russell Vincent, and Russ Allbery.
+**
+** This file should contain all innd-specific Perl linkage. Linkage
+** applicable to both innd and nnrpd should go into lib/perl.c instead.
+**
+** We are assuming Perl 5.004 or later.
+**
+** Future work:
+**
+** - What we're doing with Path headers right now doesn't work for folded
+** headers. It's also kind of gross. There has to be a better way of
+** handling this.
+**
+** - The breakdown between this file, lib/perl.c, and nnrpd/perl.c should
+** be rethought, ideally in the light of supporting multiple filters in
+** different languages.
+**
+** - We're still calling strlen() on artBody, which should be avoidable
+** since we've already walked it several times. We should just cache
+** the length somewhere for speed.
+**
+** - Variable and key names should be standardized between this and nnrpd.
+**
+** - The XS code is still calling CC* functions. The common code between
+** the two control interfaces should be factored out into the rest of
+** innd instead.
+**
+** - There's a needless perl_get_cv() call for *every message ID* offered
+** to the server right now. We need to stash whether that filter is
+** active.
+*/
+
+#include "config.h"
+
+/* Skip this entire file if DO_PERL (./configure --with-perl) isn't set. */
+#if DO_PERL
+
+#include "clibrary.h"
+#include "innd.h"
+
+#include <EXTERN.h>
+#include <perl.h>
+#include <XSUB.h>
+#include "ppport.h"
+
+#include "innperl.h"
+
+/* From art.c. Ew. Need header parsing that doesn't use globals. */
+extern char *filterPath;
+
+/*
+** Run an incoming article through the Perl article filter. Returns NULL
+** accept the article or a rejection message to reject it.
+*/
+char *
+PLartfilter(const ARTDATA *data, char *artBody, long artLen, int lines)
+{
+ dSP;
+ const ARTHEADER * hp;
+ const HDRCONTENT *hc = data->HdrContent;
+ HV * hdr;
+ CV * filter;
+ int i, rc;
+ char * p;
+ static SV * body = NULL;
+ static char buf[256];
+
+ if (!PerlFilterActive) return NULL;
+ filter = perl_get_cv("filter_art", 0);
+ if (!filter) return NULL;
+
+ /* Create %hdr and stash a copy of every known header. Path has to be
+ handled separately since it's been munged by article processing. */
+ hdr = perl_get_hv("hdr", 1);
+ for (i = 0 ; i < MAX_ARTHEADER ; i++) {
+ if (HDR_FOUND(i)) {
+ hp = &ARTheaders[i];
+ hv_store(hdr, (char *) hp->Name, hp->Size, newSVpv(HDR(i), 0), 0);
+ }
+ }
+
+ /* Store the article body. We don't want to make another copy of it,
+ since it could potentially be quite large. Instead, stash the
+ pointer in the static SV * body. We set LEN to 0 and inc the
+ refcount to tell Perl not to free it (either one should be enough).
+ Requires 5.004. In testing, this produced a 17% speed improvement
+ over making a copy of the article body for a fairly heavy filter. */
+ if (artBody) {
+ if (!body) {
+ body = newSV(0);
+ (void) SvUPGRADE(body, SVt_PV);
+ }
+ SvPVX(body) = artBody;
+ SvCUR_set(body, artLen);
+ SvLEN_set(body, 0);
+ SvPOK_on(body);
+ (void) SvREADONLY_on(body);
+ (void) SvREFCNT_inc(body);
+ hv_store(hdr, "__BODY__", 8, body, 0);
+ }
+
+ hv_store(hdr, "__LINES__", 9, newSViv(lines), 0);
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ rc = perl_call_sv((SV *) filter, G_EVAL|G_SCALAR|G_NOARGS);
+ SPAGAIN;
+
+ hv_undef(hdr);
+
+ /* Check $@, which will be set if the sub died. */
+ buf[0] = '\0';
+ if (SvTRUE(ERRSV)) {
+ syslog(L_ERROR, "Perl function filter_art died on article %s: %s",
+ HDR_FOUND(HDR__MESSAGE_ID) ? HDR(HDR__MESSAGE_ID) : "?",
+ SvPV(ERRSV, PL_na));
+ (void) POPs;
+ PerlFilter(false);
+ } else if (rc == 1) {
+ p = POPp;
+ if (p && *p)
+ strlcpy(buf, p, sizeof(buf));
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ return (buf[0] != '\0') ? buf : NULL;
+}
+
+
+/*
+** Run an incoming message ID from CHECK or IHAVE through the Perl filter.
+** Returns NULL to accept the article or a rejection message to reject it.
+*/
+char *
+PLmidfilter(char *messageID)
+{
+ dSP;
+ CV *filter;
+ int rc;
+ char *p;
+ static char buf[256];
+
+ if (!PerlFilterActive) return NULL;
+ filter = perl_get_cv("filter_messageid", 0);
+ if (!filter) return NULL;
+
+ /* Pass filter_messageid() the message ID on the Perl stack. */
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(newSVpv(messageID, 0)));
+ PUTBACK;
+ rc = perl_call_sv((SV *) filter, G_EVAL|G_SCALAR);
+ SPAGAIN;
+
+ /* Check $@, which will be set if the sub died. */
+ buf[0] = '\0';
+ if (SvTRUE(ERRSV)) {
+ syslog(L_ERROR, "Perl function filter_messageid died on id %s: %s",
+ messageID, SvPV(ERRSV, PL_na));
+ (void) POPs;
+ PerlFilter(false);
+ } else if (rc == 1) {
+ p = POPp;
+ if (p && *p)
+ strlcpy(buf, p, sizeof(buf));
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ return (buf[0] != '\0') ? buf : NULL;
+}
+
+
+/*
+** Call a Perl sub on any change in INN's mode, passing in the old and new
+** mode and the reason.
+*/
+void
+PLmode(OPERATINGMODE Mode, OPERATINGMODE NewMode, char *reason)
+{
+ dSP;
+ HV *mode;
+ CV *filter;
+
+ filter = perl_get_cv("filter_mode", 0);
+ if (!filter) return;
+
+ /* Current mode goes into $mode{Mode}, new mode in $mode{NewMode}, and
+ the reason in $mode{reason}. */
+ mode = perl_get_hv("mode", 1);
+
+ if (Mode == OMrunning)
+ hv_store(mode, "Mode", 4, newSVpv("running", 0), 0);
+ if (Mode == OMpaused)
+ hv_store(mode, "Mode", 4, newSVpv("paused", 0), 0);
+ if (Mode == OMthrottled)
+ hv_store(mode, "Mode", 4, newSVpv("throttled", 0), 0);
+
+ if (NewMode == OMrunning)
+ hv_store(mode, "NewMode", 7, newSVpv("running", 0), 0);
+ if (NewMode == OMpaused)
+ hv_store(mode, "NewMode", 7, newSVpv("paused", 0), 0);
+ if (NewMode == OMthrottled)
+ hv_store(mode, "NewMode", 7, newSVpv("throttled", 0), 0);
+
+ hv_store(mode, "reason", 6, newSVpv(reason, 0), 0);
+
+ PUSHMARK(SP);
+ perl_call_sv((SV *) filter, G_EVAL|G_DISCARD|G_NOARGS);
+
+ /* Check $@, which will be set if the sub died. */
+ if (SvTRUE(ERRSV)) {
+ syslog(L_ERROR, "Perl function filter_mode died: %s",
+ SvPV(ERRSV, PL_na));
+ (void) POPs;
+ PerlFilter(false);
+ }
+}
+
+
+/*
+** Called by CCmode, this returns the Perl filter statistics if a Perl
+** function to generate such statistics has been defined, or NULL otherwise.
+** If a string is returned, it's in newly allocated memory that must be freed
+** by the caller.
+*/
+char *
+PLstats(void)
+{
+ dSP;
+ char *argv[] = { NULL };
+
+ if (perl_get_cv("filter_stats", false) == NULL)
+ return NULL;
+ else {
+ char *stats = NULL;
+ char *result;
+
+ ENTER;
+ SAVETMPS;
+ perl_call_argv("filter_stats", G_EVAL | G_NOARGS, argv);
+ SPAGAIN;
+ result = POPp;
+ if (result != NULL && *result)
+ stats = xstrdup(result);
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return stats;
+ }
+}
+
+
+/*
+** The remainder of this file are XS callbacks visible to embedded Perl
+** code to perform various innd functions. They were originally written by
+** Ed Mooring (mooring@acm.org) on May 14, 1998, and have since been split
+** between this file and lib/perl.c (which has the ones that can also be
+** used in nnrpd). The function that registers them at startup is at the
+** end.
+*/
+
+/*
+** Add an entry to history. Takes message ID and optionally arrival,
+** article, and expire times and storage API token. If the times aren't
+** given, they default to now. If the token isn't given, that field will
+** be left empty. Returns boolean success.
+*/
+XS(XS_INN_addhist)
+{
+ dXSARGS;
+ int i;
+ char tbuff[32];
+ char* parambuf[6];
+
+ if (items < 1 || items > 5)
+ croak("Usage INN::addhist(msgid,[arrival,articletime,expire,token])");
+
+ for (i = 0; i < items; i++)
+ parambuf[i] = (char *) SvPV(ST(0), PL_na);
+
+ /* If any of the times are missing, they should default to now. */
+ if (i < 4) {
+ snprintf(tbuff, sizeof(tbuff), "%ld", (long) time(NULL));
+ for (; i < 4; i++)
+ parambuf[i] = tbuff;
+ }
+
+ /* The token defaults to an empty string. */
+ if (i == 4)
+ parambuf[4] = "";
+
+ parambuf[5] = NULL;
+
+ /* CCaddhist returns NULL on success. */
+ if (CCaddhist(parambuf))
+ XSRETURN_NO;
+ else
+ XSRETURN_YES;
+}
+
+
+/*
+** Takes the message ID of an article and returns the full article as a
+** string or undef if the article wasn't found. It will be converted from
+** wire format to native format. Note that this call isn't particularly
+** optimized or cheap.
+*/
+XS(XS_INN_article)
+{
+ dXSARGS;
+ char * msgid;
+ TOKEN token;
+ ARTHANDLE * art;
+ char * p;
+ size_t len;
+
+ if (items != 1)
+ croak("Usage: INN::article(msgid)");
+
+ /* Get the article token from the message ID and the history file. */
+ msgid = (char *) SvPV(ST(0), PL_na);
+ if (!HISlookup(History, msgid, NULL, NULL, NULL, &token)) XSRETURN_UNDEF;
+
+ /* Retrieve the article and convert it from wire format. */
+ art = SMretrieve(token, RETR_ALL);
+ if (art == NULL) XSRETURN_UNDEF;
+ p = FromWireFmt(art->data, art->len, &len);
+ SMfreearticle(art);
+
+ /* Push a copy of the article onto the Perl stack, free our temporary
+ memory allocation, and return the article to Perl. */
+ ST(0) = sv_2mortal(newSVpv(p, len));
+ free(p);
+ XSRETURN(1);
+}
+
+
+/*
+** Cancel a message by message ID; returns boolean success. Equivalent to
+** ctlinnd cancel <message>.
+*/
+XS(XS_INN_cancel)
+{
+ dXSARGS;
+ char *msgid;
+ char *parambuf[2];
+
+ if (items != 1)
+ croak("Usage: INN::cancel(msgid)");
+
+ msgid = (char *) SvPV(ST(0), PL_na);
+ parambuf[0] = msgid;
+ parambuf[1] = NULL;
+
+ /* CCcancel returns NULL on success. */
+ if (CCcancel(parambuf))
+ XSRETURN_NO;
+ else
+ XSRETURN_YES;
+}
+
+
+/*
+** Return the files for a given message ID, taken from the history file.
+** This function should really be named INN::token() and probably will be
+** some day.
+*/
+XS(XS_INN_filesfor)
+{
+ dXSARGS;
+ char *msgid;
+ TOKEN token;
+
+ if (items != 1)
+ croak("Usage: INN::filesfor(msgid)");
+
+ msgid = (char *) SvPV(ST(0), PL_na);
+ if (HISlookup(History, msgid, NULL, NULL, NULL, &token)) {
+ XSRETURN_PV(TokenToText(token));
+ } else {
+ XSRETURN_UNDEF;
+ }
+}
+
+
+/*
+** Whether message ID is in the history file; returns boolean.
+*/
+XS(XS_INN_havehist)
+{
+ dXSARGS;
+ char *msgid;
+
+ if (items != 1)
+ croak("Usage: INN::havehist(msgid)");
+
+ msgid = (char *) SvPV(ST(0), PL_na);
+ if (HIScheck(History, msgid))
+ XSRETURN_YES;
+ else
+ XSRETURN_NO;
+}
+
+
+/*
+** Takes the message ID of an article and returns the article headers as
+** a string or undef if the article wasn't found. Each line of the header
+** will end with \n.
+*/
+XS(XS_INN_head)
+{
+ dXSARGS;
+ char * msgid;
+ TOKEN token;
+ ARTHANDLE * art;
+ char * p;
+ size_t len;
+
+ if (items != 1)
+ croak("Usage: INN::head(msgid)");
+
+ /* Get the article token from the message ID and the history file. */
+ msgid = (char *) SvPV(ST(0), PL_na);
+ if (!HISlookup(History, msgid, NULL, NULL, NULL, &token)) XSRETURN_UNDEF;
+
+ /* Retrieve the article header and convert it from wire format. */
+ art = SMretrieve(token, RETR_HEAD);
+ if (art == NULL) XSRETURN_UNDEF;
+ p = FromWireFmt(art->data, art->len, &len);
+ SMfreearticle(art);
+
+ /* Push a copy of the article header onto the Perl stack, free our
+ temporary memory allocation, and return the header to Perl. */
+ ST(0) = sv_2mortal(newSVpv(p, len));
+ free(p);
+ XSRETURN(1);
+}
+
+
+/*
+** Returns the active file flag for a newsgroup or undef if it isn't in the
+** active file.
+*/
+XS(XS_INN_newsgroup)
+{
+ dXSARGS;
+ char * newsgroup;
+ NEWSGROUP * ngp;
+ char * end;
+ int size;
+
+ if (items != 1)
+ croak("Usage: INN::newsgroup(group)");
+ newsgroup = (char *) SvPV(ST(0), PL_na);
+
+ ngp = NGfind(newsgroup);
+ if (!ngp) {
+ XSRETURN_UNDEF;
+ } else {
+ /* ngp->Rest is newline-terminated; find the end. */
+ end = strchr(ngp->Rest, '\n');
+ if (end == NULL) {
+ size = strlen(ngp->Rest);
+ } else {
+ size = end - ngp->Rest;
+ }
+ ST(0) = sv_2mortal(newSVpv(ngp->Rest, size));
+ XSRETURN(1);
+ }
+}
+
+
+/*
+** Initialize the XS callbacks defined in this file.
+*/
+void
+PLxsinit(void)
+{
+ newXS("INN::addhist", XS_INN_addhist, "perl.c");
+ newXS("INN::article", XS_INN_article, "perl.c");
+ newXS("INN::cancel", XS_INN_cancel, "perl.c");
+ newXS("INN::havehist", XS_INN_havehist, "perl.c");
+ newXS("INN::head", XS_INN_head, "perl.c");
+ newXS("INN::newsgroup", XS_INN_newsgroup, "perl.c");
+ newXS("INN::filesfor", XS_INN_filesfor, "perl.c");
+}
+
+#endif /* defined(DO_PERL) */
--- /dev/null
+## $Revision: 7907 $
+include ../Makefile.global
+top = ..
+
+## If you want to do ctlinnd pause/reload/go, uncomment these lines.
+#PAUSE = pause
+#RELOAD_AND_GO = reload go
+DIFF="diff"
+
+# Added a default rule for ".csh" because Digital UNIX has a builtin
+# rule which would overwite the innshellvars file.
+.csh:
+
+CTLINND = ${PATHBIN}/ctlinnd
+FILTBIN = ${PATHFILTER}
+PATH_PERL_STARTUP_INND = ${PATHFILTER}/startup_innd.pl
+PATH_PERL_FILTER_INND = ${PATHFILTER}/filter_innd.pl
+PATH_PERL_FILTER_NNRPD = ${PATHFILTER}/filter_nnrpd.pl
+PATH_TCL_STARTUP = ${PATHFILTER}/startup.tcl
+PATH_TCL_FILTER = ${PATHFILTER}/filter.tcl
+PATH_PYTHON_FILTER_INND = ${PATHFILTER}/filter_innd.py
+PATH_PYTHON_INN_MODULE = ${PATHFILTER}/INN.py
+PATH_PYTHON_NNRPD_MODULE= ${PATHFILTER}/nnrpd.py
+PATH_NNRPAUTH = ${PATHFILTER}/nnrpd_auth.pl
+PATH_NNRPYAUTH = ${PATHFILTER}/nnrpd_auth.py
+PATH_NNRPACCESS = ${PATHFILTER}/nnrpd_access.pl
+PATH_NNRPYACCESS = ${PATHFILTER}/nnrpd_access.py
+PATH_NNRPYDYNAMIC = ${PATHFILTER}/nnrpd_dynamic.py
+
+PATH_CONFIG = ${PATHETC}/inn.conf
+PATH_CONTROLCTL = ${PATHETC}/control.ctl
+PATH_EXPIRECTL = ${PATHETC}/expire.ctl
+PATH_INNDHOSTS = ${PATHETC}/incoming.conf
+PATH_MODERATORS = ${PATHETC}/moderators
+PATH_DISTPATS = ${PATHETC}/distrib.pats
+PATH_NEWSFEEDS = ${PATHETC}/newsfeeds
+PATH_READERSCONF = ${PATHETC}/readers.conf
+PATH_NNRPDTRACK = ${PATHETC}/nnrpd.track
+PATH_SCHEMA = ${PATHETC}/overview.fmt
+PATH_NNTPPASS = ${PATHETC}/passwd.nntp
+PATH_CTLWATCH = ${PATHETC}/innwatch.ctl
+PATH_ACTSYNC_IGN = ${PATHETC}/actsync.ign
+PATH_ACTSYNC_CFG = ${PATHETC}/actsync.cfg
+PATH_MOTD = ${PATHETC}/motd.news
+PATH_STORAGECONF = ${PATHETC}/storage.conf
+PATH_CYCBUFFCONFIG = ${PATHETC}/cycbuff.conf
+PATH_INNFEEDCTL = ${PATHETC}/innfeed.conf
+PATH_BUFFINDEXED = ${PATHETC}/buffindexed.conf
+PATH_RADIUS_CONF = ${PATHETC}/radius.conf
+PATH_OVDB_CONF = ${PATHETC}/ovdb.conf
+PATH_SASL_CONF = ${PATHETC}/sasl.conf
+PATH_SUBSCRIPTIONS = ${PATHETC}/subscriptions
+
+PATH_ACTIVE = ${PATHDB}/active
+PATH_ACTIVE_TIMES = ${PATHDB}/active.times
+PATH_HISTORY = ${PATHDB}/history
+PATH_NEWSGROUPS = ${PATHDB}/newsgroups
+
+## Scripts from above, plus site-specific config files.
+REST = \
+ newsfeeds incoming.conf nnrpd.track passwd.nntp \
+ inn.conf moderators innreport.conf \
+ control.ctl expire.ctl nntpsend.ctl overview.fmt \
+ innwatch.ctl distrib.pats actsync.cfg actsync.ign \
+ motd.news storage.conf cycbuff.conf buffindexed.conf \
+ innfeed.conf startup_innd.pl filter_innd.pl filter_nnrpd.pl \
+ filter_innd.py INN.py nnrpd.py \
+ startup.tcl filter.tcl nnrpd_auth.pl nnrpd_access.pl \
+ nnrpd_access.py nnrpd_dynamic.py \
+ news2mail.cf readers.conf \
+ radius.conf nnrpd_auth.py ovdb.conf sasl.conf active.minimal \
+ newsgroups.minimal subscriptions
+
+ALL = $(MOST) $(REST)
+
+REST_INSTALLED = \
+ $D$(PATH_NEWSFEEDS) $D$(PATH_INNDHOSTS) \
+ $D$(PATH_NNRPDTRACK) $D$(PATH_NNTPPASS) \
+ $D$(PATH_CONFIG) $D$(PATH_MODERATORS) \
+ $D$(PATH_CONTROLCTL) $D$(PATH_EXPIRECTL) $D$(PATHETC)/nntpsend.ctl \
+ $D$(PATHETC)/innreport.conf \
+ $D$(PATH_CTLWATCH) $D$(PATH_DISTPATS) $D$(PATH_SCHEMA) \
+ $D$(PATH_ACTSYNC_CFG) $D$(PATH_ACTSYNC_IGN) \
+ $D$(PATH_MOTD) $D$(PATH_STORAGECONF) \
+ $D$(PATH_OVERVIEWCTL) $D$(PATH_CYCBUFFCONFIG) $D$(PATH_BUFFINDEXED) \
+ $D$(PATH_INNFEEDCTL) $D$(PATH_PERL_STARTUP_INND) \
+ $D$(PATH_PERL_FILTER_INND) $D$(PATH_PERL_FILTER_NNRPD) \
+ $D$(PATH_PYTHON_FILTER_INND) $D$(PATH_PYTHON_INN_MODULE) \
+ $D$(PATH_TCL_STARTUP) $D$(PATH_TCL_FILTER) $D$(PATH_PYTHON_NNRPD_MODULE) \
+ $D$(PATH_NNRPAUTH) $D$(PATHETC)/news2mail.cf $D$(PATH_READERSCONF) \
+ $D$(PATH_RADIUS_CONF) $D$(PATH_NNRPYAUTH) $D$(PATH_OVDB_CONF) \
+ $D$(PATH_NNRPYACCESS) $D$(PATH_NNRPYDYNAMIC) \
+ $D$(PATH_SASL_CONF) $D$(PATH_SUBSCRIPTIONS) $D$(PATH_NNRPACCESS)
+
+ALL_INSTALLED = $(MOST_INSTALLED) $(REST_INSTALLED)
+
+SPECIAL = $D$(PATH_ACTIVE) $D$(PATH_ACTIVE_TIMES) \
+ $D$(PATH_NEWSGROUPS) $D$(PATH_HISTORY)
+
+## Get new versions of everything from samples directory.
+all: $(P) $(ALL) config
+
+## Get only scripts, not per-host config files.
+most: $(MOST)
+
+## Show changes between files here and ones in samples.
+diff:
+ @$(MAKE) COPY=-${DIFF} all
+
+## Show changes between files here and installed versions.
+diff-installed:
+ @$(MAKE) COPY_RPRI=-${DIFF} COPY_RPUB=-${DIFF} COPY_XPRI=-${DIFF} COPY_XPUB=-${DIFF} $(ALL_INSTALLED)
+
+## Show what would be copied from samples directory.
+what:
+ @$(MAKE) -s 'COPY=@echo' $(ALL) | ${AWK} 'NF==2 { print $$2; }'
+
+config: $(ALL)
+ date >config
+
+## Don't use parallel rules -- we want this to be viewed carefully.
+install: all $(PAUSE) install-config $(RELOAD_AND_GO)
+reload-install: all pause install-config reload go
+install-config: update $(REST_INSTALLED) $(SPECIAL)
+
+## Install scripts, not per-host config files.
+update: all $(MOST_INSTALLED)
+ @echo "" ; echo inn.conf in site directory may have newly added parameters
+ @echo which installed inn.conf does not have. Check those parameters
+ @echo before you run innd. ; echo ""
+ date >update
+
+## Special rules for files that sould never be overwritten if they are
+## already installed. These are used only for the initial install of a
+## brand new server.
+$D$(PATH_ACTIVE): ; $(CP_DATA) active.minimal $@
+$D$(PATH_NEWSGROUPS): ; $(CP_DATA) newsgroups.minimal $@
+$D$(PATH_ACTIVE_TIMES):
+ touch $@
+ chown $(NEWSUSER) $@
+ chgrp $(NEWSGROUP) $@
+ chmod $(FILEMODE) $@
+$D$(PATH_HISTORY):
+ touch $@
+ chown $(NEWSUSER) $@
+ chgrp $(NEWSGROUP) $@
+ chmod $(FILEMODE) $@
+ $(PATHBIN)/makedbz -i -o
+
+## Remove files that are unchanged from the release version.
+clean:
+ @-for I in $(ALL) ; do \
+ cmp -s $$I ../samples/$$I && echo rm -f $$I && rm -f $$I ; \
+ done
+
+clobber distclean:
+ rm -f $(ALL) tags profiled config update
+
+tags ctags:
+ cp /dev/null tags
+
+profiled:
+ cp /dev/null profiled
+
+depend:
+
+## Commands to make private or public, read or executable files.
+COPY_RPRI = $(CP_RPRI)
+COPY_RPUB = $(CP_RPUB)
+COPY_XPRI = $(CP_XPRI)
+COPY_XPUB = $(CP_XPUB)
+
+## Order: innd, control, expire, inews, sending, misc
+$D$(PATH_INNDHOSTS): incoming.conf ; $(COPY_RPRI) $? $@
+$D$(PATH_NEWSFEEDS): newsfeeds ; $(COPY_RPUB) $? $@
+$D$(PATH_READERSCONF): readers.conf ; $(COPY_RPUB) $? $@
+$D$(PATH_RADIUS_CONF): radius.conf ; $(COPY_RPRI) $? $@
+$D$(PATH_NNRPDTRACK): nnrpd.track ; $(COPY_RPUB) $? $@
+$D$(PATH_SCHEMA): overview.fmt ; $(COPY_RPUB) $? $@
+$D$(PATH_CONTROLCTL): control.ctl ; $(COPY_RPUB) $? $@
+$D$(PATH_CTLWATCH): innwatch.ctl ; $(COPY_RPUB) $? $@
+$D$(PATH_EXPIRECTL): expire.ctl ; $(COPY_RPUB) $? $@
+$D$(PATH_CONFIG): inn.conf ; $(COPY_RPUB) $? $@
+$D$(PATH_MODERATORS): moderators ; $(COPY_RPUB) $? $@
+$D$(PATH_DISTPATS): distrib.pats ; $(COPY_RPUB) $? $@
+$D$(PATH_NNTPPASS): passwd.nntp ; $(COPY_RPRI) $? $@
+$D$(PATHETC)/nntpsend.ctl: nntpsend.ctl ; $(COPY_RPUB) $? $@
+$D$(PATHETC)/news2mail.cf: news2mail.cf ; $(COPY_RPUB) $? $@
+$D$(PATHETC)/innreport.conf: innreport.conf ; $(COPY_RPUB) $? $@
+$D$(PATH_STORAGECONF): storage.conf ; $(COPY_RPUB) $? $@
+$D$(PATH_CYCBUFFCONFIG): cycbuff.conf ; $(COPY_RPUB) $? $@
+$D$(PATH_BUFFINDEXED): buffindexed.conf ; $(COPY_RPUB) $? $@
+$D$(PATH_OVDB_CONF): ovdb.conf ; $(COPY_RPUB) $? $@
+$D$(PATH_PERL_STARTUP_INND): startup_innd.pl ; $(COPY_RPUB) $? $@
+$D$(PATH_PERL_FILTER_INND): filter_innd.pl ; $(COPY_RPUB) $? $@
+$D$(PATH_PERL_FILTER_NNRPD): filter_nnrpd.pl ; $(COPY_RPUB) $? $@
+$D$(PATH_PYTHON_FILTER_INND): filter_innd.py ; $(COPY_RPUB) $? $@
+$D$(PATH_PYTHON_INN_MODULE): INN.py ; $(COPY_RPUB) $? $@
+$D$(PATH_PYTHON_NNRPD_MODULE): nnrpd.py ; $(COPY_RPUB) $? $@
+$D$(PATH_TCL_STARTUP): startup.tcl ; $(COPY_RPUB) $? $@
+$D$(PATH_TCL_FILTER): filter.tcl ; $(COPY_RPUB) $? $@
+$D$(PATH_NNRPAUTH): nnrpd_auth.pl ; $(COPY_RPUB) $? $@
+$D$(PATH_NNRPACCESS): nnrpd_access.pl ; $(COPY_RPUB) $? $@
+$D$(PATH_NNRPYAUTH): nnrpd_auth.py ; $(COPY_RPUB) $? $@
+$D$(PATH_NNRPYACCESS): nnrpd_access.py ; $(COPY_RPUB) $? $@
+$D$(PATH_NNRPYDYNAMIC): nnrpd_dynamic.py ; $(COPY_RPUB) $? $@
+$D$(PATH_ACTSYNC_CFG): actsync.cfg ; $(COPY_RPUB) $? $@
+$D$(PATH_ACTSYNC_IGN): actsync.ign ; $(COPY_RPUB) $? $@
+$D$(PATH_MOTD): motd.news ; $(COPY_RPUB) $? $@
+$D$(PATH_INNFEEDCTL): innfeed.conf ; $(COPY_RPRI) $? $@
+$D$(PATH_SASL_CONF): sasl.conf ; $(COPY_RPUB) $? $@
+$D$(PATH_SUBSCRIPTIONS): subscriptions ; $(COPY_RPUB) $? $@
+
+REASON = 'Installing site config files from site/Makefile'
+go pause:
+ -${CTLINND} $@ $(REASON)
+reload:
+ -${CTLINND} reload all $(REASON)
+
+## Use this to just replace any changed files you might have made. Only
+## do this after you've examined the output of "make -n"!
+replace:
+ $(MAKE) COPY=cp all
+
+## Get files from the samples directory.
+COPY = $(SHELL) ./getsafe.sh
+actsync.cfg: ../samples/actsync.cfg ; $(COPY) $? $@
+actsync.ign: ../samples/actsync.ign ; $(COPY) $? $@
+control.ctl: ../samples/control.ctl ; $(COPY) $? $@
+expire.ctl: ../samples/expire.ctl ; $(COPY) $? $@
+filter.tcl: ../samples/filter.tcl ; $(COPY) $? $@
+nnrpd_auth.pl: ../samples/nnrpd_auth.pl ; $(COPY) $? $@
+nnrpd_access.pl: ../samples/nnrpd_access.pl ; $(COPY) $? $@
+nnrpd_auth.py: ../samples/nnrpd_auth.py ; $(COPY) $? $@
+nnrpd_access.py: ../samples/nnrpd_access.py ; $(COPY) $? $@
+nnrpd_dynamic.py: ../samples/nnrpd_dynamic.py ; $(COPY) $? $@
+filter_innd.pl: ../samples/filter_innd.pl ; $(COPY) $? $@
+filter_nnrpd.pl: ../samples/filter_nnrpd.pl ; $(COPY) $? $@
+filter_innd.py: ../samples/filter_innd.py ; $(COPY) $? $@
+INN.py: ../samples/INN.py ; $(COPY) $? $@
+nnrpd.py: ../samples/nnrpd.py ; $(COPY) $? $@
+incoming.conf: ../samples/incoming.conf ; $(COPY) $? $@
+inn.conf: ../samples/inn.conf ; $(COPY) $? $@
+innreport.conf: ../samples/innreport.conf ; $(COPY) $? $@
+storage.conf: ../samples/storage.conf ; $(COPY) $? $@
+cycbuff.conf: ../samples/cycbuff.conf ; $(COPY) $? $@
+buffindexed.conf: ../samples/buffindexed.conf ; $(COPY) $? $@
+ovdb.conf: ../samples/ovdb.conf ; $(COPY) $? $@
+innwatch.ctl: ../samples/innwatch.ctl ; $(COPY) $? $@
+innfeed.conf: ../samples/innfeed.conf ; $(COPY) $? $@
+moderators: ../samples/moderators ; $(COPY) $? $@
+distrib.pats: ../samples/distrib.pats ; $(COPY) $? $@
+motd.news: ../samples/motd.news ; $(COPY) $? $@
+news2mail.cf: ../samples/news2mail.cf ; $(COPY) $? $@
+newsfeeds: ../samples/newsfeeds ; $(COPY) $? $@
+nnrpd.track: ../samples/nnrpd.track ; $(COPY) $? $@
+nntpsend.ctl: ../samples/nntpsend.ctl ; $(COPY) $? $@
+overview.fmt: ../samples/overview.fmt ; $(COPY) $? $@
+parsecontrol: ../samples/parsecontrol ; $(COPY) $? $@
+passwd.nntp: ../samples/passwd.nntp ; $(COPY) $? $@
+readers.conf: ../samples/readers.conf ; $(COPY) $? $@
+radius.conf: ../samples/radius.conf ; $(COPY) $? $@
+startup.tcl: ../samples/startup.tcl ; $(COPY) $? $@
+startup_innd.pl: ../samples/startup_innd.pl ; $(COPY) $? $@
+subscriptions: ../samples/subscriptions ; $(COPY) $? $@
+sasl.conf: ../samples/sasl.conf ; $(COPY) $? $@
+active.minimal: ../samples/active.minimal ; $(COPY) $? $@
+newsgroups.minimal: ../samples/newsgroups.minimal ; $(COPY) $? $@
--- /dev/null
+#!/usr/bin/perl -w
+# fixscript will replace this line with require innshellvars.pl
+
+##############################################################################
+# perl-nocem - a NoCeM-on-spool implementation for INN 2.x.
+# Copyright 2000 by Miquel van Smoorenburg <miquels@cistron.nl>
+# Copyright 2001 by Marco d'Itri <md@linux.it>
+# This program is licensed under the terms of the GNU General Public License.
+#
+# List of changes:
+#
+# 2002: Patch by Steven M. Christey for untrusted printf input.
+# 2007: Patch by Christoph Biedl for checking a timeout.
+# Documentation improved by Jeffrey M. Vinocur (2002), Russ Allbery (2006)
+# and Julien Elie (2007).
+#
+##############################################################################
+
+require 5.00403;
+use strict;
+
+# XXX FIXME I haven't been able to load it only when installed.
+# If nobody can't fix it just ship the program with this line commented.
+#use Time::HiRes qw(time);
+
+my $keyring = $inn::pathetc . '/pgp/ncmring.gpg';
+
+# XXX To be moved to a config file.
+#sub local_want_cancel_id {
+# my ($group, $hdrs) = @_;
+#
+## Hippo has too many false positives to be useful outside of pr0n groups
+# if ($hdrs->{issuer} =~ /(?:Ultra|Spam)Hippo/) {
+# foreach (split(/,/, $group)) {
+# return 1 if /^alt\.(?:binar|sex)/;
+# }
+# return 0;
+# }
+# return 1;
+#}
+
+# no user serviceable parts below this line ###################################
+
+# global variables
+my ($working, $got_sighup, $got_sigterm, @ncmperm, $cancel);
+my $use_syslog = 0;
+my $log_open = 0;
+my $nntp_open = 0;
+my $last_cancel = 0;
+my $socket_timeout = $inn::peertimeout - 100;
+
+my $logfile = $inn::pathlog . '/perl-nocem.log';
+
+# initialization and main loop ###############################################
+
+eval { require Sys::Syslog; import Sys::Syslog; $use_syslog = 1; };
+
+if ($use_syslog) {
+ eval "sub Sys::Syslog::_PATH_LOG { '/dev/log' }" if $^O eq 'dec_osf';
+ Sys::Syslog::setlogsock('unix') if $^O =~ /linux|dec_osf/;
+ openlog('nocem', '', $inn::syslog_facility);
+}
+
+if (not $inn::gpgv) {
+ logmsg('cannot find the gpgv binary', 'err');
+ sleep 5;
+ exit 1;
+}
+
+if ($inn::version and not $inn::version =~ /^INN 2\.[0123]\./) {
+ $cancel = \&cancel_nntp;
+} else {
+ $cancel = \&cancel_ctlinnd;
+}
+
+$SIG{HUP} = \&hup_handler;
+$SIG{INT} = \&term_handler;
+$SIG{TERM} = \&term_handler;
+$SIG{PIPE} = \&term_handler;
+
+logmsg('starting up');
+
+unless (read_ctlfile()) {
+ sleep 5;
+ exit 1;
+}
+
+while (<STDIN>) {
+ chop;
+ $working = 1;
+ do_nocem($_);
+ $working = 0;
+ term_handler() if $got_sigterm;
+ hup_handler() if $got_sighup;
+}
+
+logmsg('exiting because of EOF', 'debug');
+exit 0;
+
+##############################################################################
+
+# Process one NoCeM notice.
+sub do_nocem {
+ my $token = shift;
+ my $start = time;
+
+ # open the article and verify the notice
+ my $artfh = open_article($token);
+ return if not defined $artfh;
+ my ($msgid, $nid, $issuer, $nocems) = read_nocem($artfh);
+ close $artfh;
+ return unless $nocems;
+
+ &$cancel($nocems);
+ logmsg("Articles cancelled: " . join(' ', @$nocems), 'debug');
+ my $diff = (time - $start) || 0.01;
+ my $nr = scalar @$nocems;
+ logmsg(sprintf("processed notice %s by %s (%d ids, %.5f s, %.1f/s)",
+ $nid, $issuer, $nr, $diff, $nr / $diff));
+}
+
+# - Check if it is a PGP signed NoCeM notice
+# - See if we want it
+# - Then check PGP signature
+sub read_nocem {
+ my $artfh = shift;
+
+ # Examine the first 200 lines to see if it is a PGP signed NoCeM.
+ my $ispgp = 0;
+ my $isncm = 0;
+ my $inhdr = 1;
+ my $i = 0;
+ my $body = '';
+ my ($from, $msgid);
+ while (<$artfh>) {
+ last if $i++ > 200;
+ s/\r\n$/\n/;
+ if ($inhdr) {
+ if (/^$/) {
+ $inhdr = 0;
+ } elsif (/^From:\s+(.*)\s*$/i) {
+ $from = $1;
+ } elsif (/^Message-ID:\s+(<.*>)/i) {
+ $msgid = $1;
+ }
+ } else {
+ $body .= $_;
+ $ispgp = 1 if /^-----BEGIN PGP SIGNED MESSAGE-----/;
+ if (/^\@\@BEGIN NCM HEADERS/) {
+ $isncm = 1;
+ last;
+ }
+ }
+ }
+
+ # must be a PGP signed NoCeM.
+ if (not $ispgp) {
+ logmsg("Article $msgid: not PGP signed", 'debug');
+ return;
+ }
+ if (not $isncm) {
+ logmsg("Article $msgid: not a NoCeM", 'debug');
+ return;
+ }
+
+ # read the headers of this NoCeM, and check if it's supported.
+ my %hdrs;
+ while (<$artfh>) {
+ s/\r\n/\n/;
+ $body .= $_;
+ last if /^\@\@BEGIN NCM BODY/;
+ my ($key, $val) = /^([^:]+)\s*:\s*(.*)$/;
+ $hdrs{lc $key} = $val;
+ }
+ foreach (qw(action issuer notice-id type version)) {
+ next if $hdrs{$_};
+ logmsg("Article $msgid: missing $_ pseudo header", 'debug');
+ return;
+ }
+ return if not supported_nocem($msgid, \%hdrs);
+
+ # decide if we want it.
+ if (not want_nocem(\%hdrs)) {
+ logmsg("Article $msgid: unwanted ($hdrs{issuer}/$hdrs{type})", 'debug');
+ return;
+ }
+# XXX want_hier() not implemented
+# if ($hdrs{hierarchies} and not want_hier($hdrs{hierarchies})) {
+# logmsg("Article $msgid: unwanted hierarchy ($hdrs{hierarchies})",
+# 'debug');
+# return;
+# }
+
+ # We do want it, so read the entire article. Also copy it to
+ # a temp file so that we can check the PGP signature when done.
+ my $tmpfile = "$inn::pathtmp/nocem.$$";
+ if (not open(OFD, ">$tmpfile")) {
+ logmsg("cannot open temp file $tmpfile: $!", 'err');
+ return;
+ }
+ print OFD $body;
+ undef $body;
+
+ # process NoCeM body.
+ my $inbody = 1;
+ my @nocems;
+ my ($lastid, $lastgrp);
+ while (<$artfh>) {
+ s/\r\n$/\n/;
+ print OFD;
+ $inbody = 0 if /^\@\@END NCM BODY/;
+ next if not $inbody or /^#/;
+
+ my ($id, $grp) = /^(\S*)\s+(\S+)/;
+ next if not $grp;
+ if ($id) {
+ push @nocems, $lastid
+ if $lastid and want_cancel_id($lastgrp, \%hdrs);
+ $lastid = $id;
+ $lastgrp = $grp;
+ } else {
+ $lastgrp .= ',' . $grp;
+ }
+ }
+ push @nocems, $lastid if $lastid and want_cancel_id($lastgrp, \%hdrs);
+ close OFD;
+
+ # at this point we need to verify the PGP signature.
+ return if not @nocems;
+ my $e = pgp_check($hdrs{issuer}, $msgid, $tmpfile);
+ unlink $tmpfile;
+ return if not $e;
+
+ return ($msgid, $hdrs{'notice-id'}, $hdrs{issuer}, \@nocems);
+}
+
+# XXX not implemented: code to discard notices for groups we don't carry
+sub want_cancel_id {
+ my ($group, $hdrs) = @_;
+
+ return local_want_cancel_id(@_) if defined &local_want_cancel_id;
+ 1;
+}
+
+# Do we actually want this NoCeM?
+sub want_nocem {
+ my $hdrs = shift;
+
+ foreach (@ncmperm) {
+ my ($issuer, $type) = split(/\001/);
+ if ($hdrs->{issuer} =~ /$issuer/i) {
+ return 1 if '*' eq $type or lc $hdrs->{type} eq $type;
+ }
+ }
+ return 0;
+}
+
+sub supported_nocem {
+ my ($msgid, $hdrs) = @_;
+
+ if ($hdrs->{version} !~ /^0\.9[0-9]?$/) {
+ logmsg("Article $msgid: version $hdrs->{version} not supported",
+ 'debug');
+ return 0;
+ }
+ if ($hdrs->{action} ne 'hide') {
+ logmsg("Article $msgid: action $hdrs->{action} not supported",
+ 'debug');
+ return 0;
+ }
+ return 1;
+}
+
+# Check the PGP signature on an article.
+sub pgp_check {
+ my ($issuer, $msgid, $art) = @_;
+
+ # fork and spawn a child
+ my $pid = open(PFD, '-|');
+ if (not defined $pid) {
+ logmsg("pgp_check: cannot fork: $!", 'err');
+ return 0;
+ }
+ if ($pid == 0) {
+ open(STDERR, '>&STDOUT');
+ exec($inn::gpgv, '--status-fd=1',
+ $keyring ? '--keyring=' . $keyring : '', $art);
+ exit 126;
+ }
+
+ # Read the result and check status code.
+ local $_ = join('', <PFD>);
+ my $status = 0;
+ if (not close PFD) {
+ if ($? >> 8) {
+ $status = $? >> 8;
+ } else {
+ logmsg("Article $msgid: $inn::gpgv killed by signal " . ($? & 255));
+ return 0;
+ }
+ }
+# logmsg("Command line was: $inn::gpgv --status-fd=1"
+# . ($keyring ? ' --keyring=' . $keyring : '') . " $art", 'debug');
+# logmsg("Full PGP output: >>>$_<<<", 'debug');
+
+ if (/^\[GNUPG:\]\s+GOODSIG\s+\S+\s+(.*)/m) {
+ return 1 if $1 =~ /\Q$issuer\E/;
+ logmsg("Article $msgid: signed by $1 instead of $issuer");
+ } elsif (/^\[GNUPG:\]\s+NO_PUBKEY\s+(\S+)/m) {
+ logmsg("Article $msgid: $issuer (ID $1) not in keyring");
+ } elsif (/^\[GNUPG:\]\s+BADSIG\s+\S+\s+(.*)/m) {
+ logmsg("Article $msgid: bad signature from $1");
+ } elsif (/^\[GNUPG:\]\s+BADARMOR/m or /^\[GNUPG:\]\s+UNEXPECTED/m) {
+ logmsg("Article $msgid: malformed signature");
+ } elsif (/^\[GNUPG:\]\s+ERRSIG\s+(\S+)/m) {
+ # safety net: we get there if we don't know about some token
+ logmsg("Article $msgid: unknown error (ID $1)");
+ } else {
+ # some other error we don't know about happened.
+ # 126 is returned by the child if exec fails.
+ s/ at \S+ line \d+\.\n$//; s/\n/_/;
+ logmsg("Article $msgid: $inn::gpgv exited "
+ . (($status == 126) ? "($_)" : "with status $status"), 'err');
+ }
+ return 0;
+}
+
+# Read article.
+sub open_article {
+ my $token = shift;
+
+ if ($token =~ /^\@.+\@$/) {
+ my $pid = open(ART, '-|');
+ if ($pid < 0) {
+ logmsg('Cannot fork: ' . $!, 'err');
+ return undef;
+ }
+ if ($pid == 0) {
+ exec("$inn::newsbin/sm", '-q', $token) or
+ logmsg("Cannot exec sm: $!", 'err');
+ return undef;
+ }
+ return *ART;
+ } else {
+ return *ART if open(ART, $token);
+ logmsg("Cannot open article $token: $!", 'err');
+ }
+ return undef;
+}
+
+# Cancel a number of Message-IDs. We use ctlinnd to do this,
+# and we run up to 15 of them at the same time (10 usually).
+sub cancel_ctlinnd {
+ my @ids = @{$_[0]};
+
+ while (@ids > 0) {
+ my $max = @ids <= 15 ? @ids : 10;
+ for (my $i = 1; $i <= $max; $i++) {
+ my $msgid = shift @ids;
+ my $pid;
+ sleep 5 until (defined ($pid = fork));
+ if ($pid == 0) {
+ exec "$inn::pathbin/ctlinnd", '-s', '-t', '180',
+ 'cancel', $msgid;
+ exit 126;
+ }
+# logmsg("cancelled: $msgid [$i/$max]", 'debug');
+ }
+ # Now wait for all children.
+ while ((my $pid = wait) > 0) {
+ next unless $?;
+ if ($? >> 8) {
+ logmsg("Child $pid died with status " . ($? >> 8), 'err');
+ } else {
+ logmsg("Child $pid killed by signal " . ($? & 255), 'err');
+ }
+ }
+ }
+}
+
+sub cancel_nntp {
+ my $ids = shift;
+ my $r;
+
+ if ($nntp_open and time - $socket_timeout > $last_cancel) {
+ logmsg('Close socket for timeout');
+ close (NNTP);
+ $nntp_open = 0;
+ }
+ if (not $nntp_open) {
+ use Socket;
+ if (not socket(NNTP, PF_UNIX, SOCK_STREAM, 0)) {
+ logmsg("socket: $!", 'err');
+ goto ERR;
+ }
+ if (not connect(NNTP, sockaddr_un($inn::pathrun . '/nntpin'))) {
+ logmsg("connect: $!", 'err');
+ goto ERR;
+ }
+ if (($r = <NNTP>) !~ /^200 /) {
+ $r =~ s/\r\n$//;
+ logmsg("bad reply from server: $r", 'err');
+ goto ERR;
+ }
+ select NNTP; $| = 1; select STDOUT;
+ print NNTP "MODE CANCEL\r\n";
+ if (($r = <NNTP>) !~ /^284 /) {
+ $r =~ s/\r\n$//;
+ logmsg("MODE CANCEL not supported: $r", 'err');
+ goto ERR;
+ }
+ $nntp_open = 1;
+ }
+ foreach (@$ids) {
+ print NNTP "$_\r\n";
+ if (($r = <NNTP>) !~ /^289/) {
+ $r =~ s/\r\n$//;
+ logmsg("cannot cancel $_: $r", 'err');
+ goto ERR;
+ }
+ }
+ $last_cancel = time;
+ return;
+
+ERR:
+ # discard unusable socket
+ close (NNTP);
+ logmsg('Switching to ctlinnd...', 'err');
+ cancel_ctlinnd($ids);
+ $cancel = \&cancel_ctlinnd;
+}
+
+sub read_ctlfile {
+ my $permfile = $inn::pathetc . '/nocem.ctl';
+
+ unless (open(CTLFILE, $permfile)) {
+ logmsg("Cannot open $permfile: $!", 'err');
+ return 0;
+ }
+ while (<CTLFILE>) {
+ chop;
+ s/^\s+//; s/\s+$//;
+ next if /^#/ or /^$/;
+ my ($issuer, $type) = split(/:/, lc $_);
+ logmsg("Cannot parse nocem.ctl line <<$_>>", 'err')
+ if not $issuer and $type;
+ $type =~ s/\s//g;
+ push @ncmperm, "$issuer\001$_" foreach split(/,/, $type);
+ }
+ close CTLFILE;
+ return 1;
+}
+
+sub logmsg {
+ my ($msg, $lvl) = @_;
+
+ if (not $use_syslog) {
+ if ($log_open == 0) {
+ open(LOG, ">>$logfile") or die "Cannot open log: $!";
+ $log_open = 1;
+ select LOG; $| = 1; select STDOUT;
+ }
+ $lvl ||= 'notice';
+ print LOG "$lvl: $msg\n";
+ return;
+ }
+ syslog($lvl || 'notice', '%s', $msg);
+}
+
+sub hup_handler {
+ $got_sighup = 1;
+ return if $working;
+ close LOG;
+ $log_open = 0;
+}
+
+sub term_handler {
+ $got_sigterm = 1;
+ return if $working;
+ logmsg('exiting because of signal');
+ exit 1;
+}
+
+# lint food
+print $inn::pathrun.$inn::pathlog.$inn::pathetc.$inn::newsbin.$inn::pathbin
+ .$inn::pathtmp.$inn::peertimeout.$inn::syslog_facility;
+
+__END__
+
+=head1 NAME
+
+perl-nocem - A NoCeM-on-spool implementation for S<INN 2.x>
+
+=head1 SYNOPSIS
+
+perl-nocem
+
+=head1 DESCRIPTION
+
+NoCeM, which is pronounced I<No See 'Em>, is a protocol enabling
+authenticated third-parties to issue notices which can be used
+to cancel unwanted articles (like spam and articles in moderated
+newsgroups which were not approved by their moderators). It can
+also be used by readers as a I<third-party killfile>. It is
+intended to eventually replace the protocol for third-party cancel
+messages.
+
+B<perl-nocem> processes third-party, PGP-signed article cancellation
+notices. It is possible not to honour all NoCeM notices but only those
+which are sent by people whom you trust (that is to say if you trust
+the PGP key they use to sign their NoCeM notices). Indeed, it is up
+to you to decide whether you wish to honour their notices, depending
+on the criteria they use.
+
+Processing NoCeM notices is easy to set up:
+
+=over 4
+
+=item 1.
+
+Import the keys of the NoCeM issuers you trust in order to check
+the authenticity of their notices. You can do:
+
+ gpg --no-default-keyring --primary-keyring <pathetc>/pgp/ncmring.gpg --import <key-file>
+
+where <pathetc> is the value of the I<pathetc> parameter set in F<inn.conf>
+and <key-file> the file containing the key(s) to import. The keyring
+must be located in I<pathetc>/pgp/ncmring.gpg (create the directory
+before using B<gpg>). For old PGP-generated keys, you may have to use
+B<--allow-non-selfsigned-uid> if they are not properly self-signed,
+but anyone creating a key really should self-sign the key. Current
+PGP implementations do this automatically.
+
+The keys of NoCeM issuers can be found in the web site of I<The NoCeM Registry>:
+L<http://www.xs4all.nl/~rosalind/nocemreg/nocemreg.html>. You can even
+download there a unique file which contains all the keys.
+
+=item 2.
+
+Create a F<nocem.ctl> config file in I<pathetc> indicating the NoCeM issuers
+and notices you want to follow. This permission file contains lines like:
+
+ annihilator-1:*
+ clewis@ferret.ocunix:mmf
+ stephane@asynchrone:mmf,openproxy,spam
+
+This will remove all articles for which the issuer (first part of the line,
+before the colon C<:>) has issued NoCeM notices corresponding to the
+criteria specified after the colon.
+
+You will also find information about that on the web site of
+I<The NoCeM Registry>.
+
+=item 3.
+
+Add to the F<newsfeeds> file an entry like this one in order to feed
+B<perl-nocem> the NoCeM notices posted to alt.nocem.misc and
+news.lists.filters:
+
+ nocem!\
+ :!*,alt.nocem.misc,news.lists.filters\
+ :Tc,Wf,Ap:<pathbin>/perl-nocem
+
+with the correct path to B<perl-nocem>, located in <pathbin>. Then, reload
+the F<newsfeeds> file (C<ctlinnd reload newsfeeds 'NoCeM channel feed'>).
+
+Note that you should at least carry news.lists.filters on your news
+server (or other newsgroups where NoCeM notices are sent) if you wish
+to process them.
+
+=item 4.
+
+Everything should now work. However, do not hesitate to manually test
+B<perl-nocem> with a NoCeM notice, using:
+
+ grephistory '<Message-ID>' | perl-nocem
+
+Indeed, B<perl-nocem> expects tokens on its standard input, and
+B<grephistory> can easily give it the token of a known article,
+thanks to its Message-ID.
+
+=back
+
+When you have verified that everything works, you can eventually turn
+off regular spam cancels, if you want, not processing any longer
+cancels containing C<cyberspam> in the Path: header (see the
+I<refusecybercancels> parameter in F<inn.conf>).
+
+=head1 FILES
+
+=over 4
+
+=item I<pathbin>/perl-nocem
+
+The Perl script itself used to process NoCeM notices.
+
+=item I<pathetc>/nocem.ctl
+
+The configuration file which specifies the NoCeM notices to be processed.
+
+=item I<pathetc>/pgp/ncmring.gpg
+
+The keyring which contains the public keys of trusted NoCeM issuers.
+
+=back
+
+=head1 BUGS
+
+The Subject: header is not checked for the @@NCM string and there is no
+check for the presence of the References: header.
+
+The Newsgroups: pseudo header is not checked, but this can be done in
+local_want_cancel_id().
+
+The Hierarchies: header is ignored.
+
+=head1 HISTORY
+
+Copyright 2000 by Miquel van Smoorenburg <miquels@cistron.nl>.
+
+Copyright 2001 by Marco d'Itri <md@linux.it>.
+
+$Id: perl-nocem.in 7733 2008-04-06 09:16:20Z iulius $
+
+=head1 SEE ALSO
+
+gpgv(1), grephistory(1), inn.conf(5), newsfeeds(5), pgp(1).
+
+=cut
--- /dev/null
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "PERL-NOCEM 8"
+.TH PERL-NOCEM 8 "2008-04-06" "INN 2.4.4" "InterNetNews Documentation"
+.SH "NAME"
+perl\-nocem \- A NoCeM\-on\-spool implementation for INN\ 2.x
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+perl-nocem
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+NoCeM, which is pronounced \fINo See 'Em\fR, is a protocol enabling
+authenticated third-parties to issue notices which can be used
+to cancel unwanted articles (like spam and articles in moderated
+newsgroups which were not approved by their moderators). It can
+also be used by readers as a \fIthird-party killfile\fR. It is
+intended to eventually replace the protocol for third-party cancel
+messages.
+.PP
+\&\fBperl-nocem\fR processes third\-party, PGP-signed article cancellation
+notices. It is possible not to honour all NoCeM notices but only those
+which are sent by people whom you trust (that is to say if you trust
+the \s-1PGP\s0 key they use to sign their NoCeM notices). Indeed, it is up
+to you to decide whether you wish to honour their notices, depending
+on the criteria they use.
+.PP
+Processing NoCeM notices is easy to set up:
+.IP "1." 4
+Import the keys of the NoCeM issuers you trust in order to check
+the authenticity of their notices. You can do:
+.Sp
+.Vb 1
+\& gpg \-\-no\-default\-keyring \-\-primary\-keyring <pathetc>/pgp/ncmring.gpg \-\-import <key\-file>
+.Ve
+.Sp
+where <pathetc> is the value of the \fIpathetc\fR parameter set in \fIinn.conf\fR
+and <key\-file> the file containing the key(s) to import. The keyring
+must be located in \fIpathetc\fR/pgp/ncmring.gpg (create the directory
+before using \fBgpg\fR). For old PGP-generated keys, you may have to use
+\&\fB\-\-allow\-non\-selfsigned\-uid\fR if they are not properly self\-signed,
+but anyone creating a key really should self-sign the key. Current
+\&\s-1PGP\s0 implementations do this automatically.
+.Sp
+The keys of NoCeM issuers can be found in the web site of \fIThe NoCeM Registry\fR:
+<http://www.xs4all.nl/~rosalind/nocemreg/nocemreg.html>. You can even
+download there a unique file which contains all the keys.
+.IP "2." 4
+Create a \fInocem.ctl\fR config file in \fIpathetc\fR indicating the NoCeM issuers
+and notices you want to follow. This permission file contains lines like:
+.Sp
+.Vb 3
+\& annihilator\-1:*
+\& clewis@ferret.ocunix:mmf
+\& stephane@asynchrone:mmf,openproxy,spam
+.Ve
+.Sp
+This will remove all articles for which the issuer (first part of the line,
+before the colon \f(CW\*(C`:\*(C'\fR) has issued NoCeM notices corresponding to the
+criteria specified after the colon.
+.Sp
+You will also find information about that on the web site of
+\&\fIThe NoCeM Registry\fR.
+.IP "3." 4
+Add to the \fInewsfeeds\fR file an entry like this one in order to feed
+\&\fBperl-nocem\fR the NoCeM notices posted to alt.nocem.misc and
+news.lists.filters:
+.Sp
+.Vb 3
+\& nocem!\e
+\& :!*,alt.nocem.misc,news.lists.filters\e
+\& :Tc,Wf,Ap:<pathbin>/perl\-nocem
+.Ve
+.Sp
+with the correct path to \fBperl-nocem\fR, located in <pathbin>. Then, reload
+the \fInewsfeeds\fR file (\f(CW\*(C`ctlinnd reload newsfeeds 'NoCeM channel feed'\*(C'\fR).
+.Sp
+Note that you should at least carry news.lists.filters on your news
+server (or other newsgroups where NoCeM notices are sent) if you wish
+to process them.
+.IP "4." 4
+Everything should now work. However, do not hesitate to manually test
+\&\fBperl-nocem\fR with a NoCeM notice, using:
+.Sp
+.Vb 1
+\& grephistory '<Message\-ID>' | perl\-nocem
+.Ve
+.Sp
+Indeed, \fBperl-nocem\fR expects tokens on its standard input, and
+\&\fBgrephistory\fR can easily give it the token of a known article,
+thanks to its Message\-ID.
+.PP
+When you have verified that everything works, you can eventually turn
+off regular spam cancels, if you want, not processing any longer
+cancels containing \f(CW\*(C`cyberspam\*(C'\fR in the Path: header (see the
+\&\fIrefusecybercancels\fR parameter in \fIinn.conf\fR).
+.SH "FILES"
+.IX Header "FILES"
+.IP "\fIpathbin\fR/perl\-nocem" 4
+.IX Item "pathbin/perl-nocem"
+The Perl script itself used to process NoCeM notices.
+.IP "\fIpathetc\fR/nocem.ctl" 4
+.IX Item "pathetc/nocem.ctl"
+The configuration file which specifies the NoCeM notices to be processed.
+.IP "\fIpathetc\fR/pgp/ncmring.gpg" 4
+.IX Item "pathetc/pgp/ncmring.gpg"
+The keyring which contains the public keys of trusted NoCeM issuers.
+.SH "BUGS"
+.IX Header "BUGS"
+The Subject: header is not checked for the @@NCM string and there is no
+check for the presence of the References: header.
+.PP
+The Newsgroups: pseudo header is not checked, but this can be done in
+\&\fIlocal_want_cancel_id()\fR.
+.PP
+The Hierarchies: header is ignored.
+.SH "HISTORY"
+.IX Header "HISTORY"
+Copyright 2000 by Miquel van Smoorenburg <miquels@cistron.nl>.
+.PP
+Copyright 2001 by Marco d'Itri <md@linux.it>.
+.PP
+$Id: perl-nocem.8 7733 2008-04-06 09:16:20Z iulius $
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIgpgv\fR\|(1), \fIgrephistory\fR\|(1), \fIinn.conf\fR\|(5), \fInewsfeeds\fR\|(5), \fIpgp\fR\|(1).
--- /dev/null
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.\"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "INN.CONF 5"
+.TH INN.CONF 5 "2008-04-06" "INN 2.4.5" "InterNetNews Documentation"
+.SH "NAME"
+inn.conf \- Configuration data for InterNetNews programs
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fIinn.conf\fR in \fIpathetc\fR is the primary general configuration file for
+all InterNetNews programs. Settings which control the general operation
+of various programs, as well as the paths to all portions of the news
+installation, are found here. The \s-1INNCONF\s0 environment variable, if set,
+specifies an alternate path to \fIinn.conf\fR.
+.PP
+This file is intended to be fairly static. Any changes made to it will
+generally not affect any running programs until they restart. Unlike
+nearly every other configuration file, \fIinn.conf\fR cannot be reloaded
+dynamically using \fIctlinnd\fR\|(8); \fIinnd\fR\|(8) must be stopped and restarted for
+relevant changes to \fIinn.conf\fR to take effect (\f(CW\*(C`ctlinnd xexec innd\*(C'\fR is
+the fastest way to do this.)
+.PP
+Blank lines and lines starting with a number sign (\f(CW\*(C`#\*(C'\fR) are ignored. All
+other lines specify parameters, and should be of the following form:
+.PP
+.Vb 1
+\& <name>: <value>
+.Ve
+.PP
+(Any amount of whitespace can be put after the colon and is optional.) If
+the value contains embedded whitespace or any of the characers \f(CW\*(C`[]<\*(C'\fR\*(L"\e:>,
+it must be enclosed in double quotes (\*(R""). A backslash (\f(CW\*(C`\e\*(C'\fR) can be used
+to escape quotes and backslashes inside double quotes. <name> is
+case\-sensitive; \f(CW\*(C`server\*(C'\fR is not the same as \f(CW\*(C`Server\*(C'\fR or \f(CW\*(C`SERVER\*(C'\fR.
+(\fIinn.conf\fR parameters are generally all in lowercase.)
+.PP
+If <name> occurs more than once in the file, the first value is used.
+Some parameters specified in the file may be overridden by environment
+variables. Most parameters have default values if not specified in
+\&\fIinn.conf\fR; those defaults are noted in the description of each
+parameter.
+.PP
+Many parameters take a boolean value. For all such parameters, the value
+may be specified as \f(CW\*(C`true\*(C'\fR, \f(CW\*(C`yes\*(C'\fR, or \f(CW\*(C`on\*(C'\fR to turn it on and may be any
+of \f(CW\*(C`false\*(C'\fR, \f(CW\*(C`no\*(C'\fR, or \f(CW\*(C`off\*(C'\fR to turn it off. The case of these values is
+significant.
+.PP
+This documentation is extremely long and organized as a reference manual
+rather than as a tutorial. If this is your first exposure to \s-1INN\s0 and
+these parameters, it would be better to start by reading other man pages
+and referring to this one only when an \fIinn.conf\fR parameter is explicitly
+mentioned. Those parameters which need to be changed when setting up a
+new server are discussed in \fI\s-1INSTALL\s0\fR.
+.SH "PARAMETERS"
+.IX Header "PARAMETERS"
+.Sh "General Settings"
+.IX Subsection "General Settings"
+These parameters are used by a wide variety of different components of
+\&\s-1INN\s0.
+.IP "\fIdomain\fR" 4
+.IX Item "domain"
+This should be the domain name of the local host. It should not have a
+leading period, and it should not be a full host address. It is used only
+if the \fIGetFQDN()\fR routine in \fIlibinn\fR\|(3) cannot get the fully-qualified
+domain name by using either the \fIgethostname\fR\|(3) or \fIgethostbyname\fR\|(3) calls.
+The check is very simple; if either routine returns a name with a period
+in it, then it is assumed to have the full domain name. As this parameter
+is rarely used, do not use it to affect the righthand side of
+autogenerated Message\-IDs; see instead \fIvirtualhost\fR and \fIdomain\fR in
+readers.conf. The default value is unset.
+.IP "\fIinnflags\fR" 4
+.IX Item "innflags"
+The flags to pass to innd on startup. See \fIinnd\fR\|(8) for details on the
+possible flags. The default value is unset.
+.IP "\fImailcmd\fR" 4
+.IX Item "mailcmd"
+The path to the program to be used for mailing reports and control
+messages. The default is \fIpathbin\fR/innmail. This should not normally
+need to be changed.
+.IP "\fImta\fR" 4
+.IX Item "mta"
+The command to use when mailing postings to moderators and for the use of
+\&\fIinnmail\fR\|(1). The message, with headers and an added To: header, will be
+piped into this program. The string \f(CW%s\fR, if present, will be replaced
+by the e\-mail address of the moderator. It's strongly recommended for
+this command to include \f(CW%s\fR on the command line rather than use the
+addresses in the To: and Cc: headers of the message, since the latter
+approach allows the news server to be abused as a mechanism to send mail
+to arbitrary addresses and will result in unexpected behavior. There is
+no default value for this parameter; it must be set in \fIinn.conf\fR or a
+fatal error message will be logged via syslog.
+.Sp
+For most systems, \f(CW\*(C`/usr/lib/sendmail \-oi \-oem %s\*(C'\fR (adjusted for the
+correct path to sendmail) is a good choice.
+.IP "\fIpathhost\fR" 4
+.IX Item "pathhost"
+What to put into the Path: header to represent the local site. This is
+added to the Path: header of all articles that pass through the system,
+including locally posted articles, and is also used when processing some
+control messages and when naming the server in status reports. There is
+no default value; this parameter must be set in \fIinn.conf\fR or \s-1INN\s0 will
+not start. A good value to use is the fully-qualified hostname of the
+system.
+.IP "\fIserver\fR" 4
+.IX Item "server"
+The name of the default \s-1NNTP\s0 server. If \fInnrpdposthost\fR is not set and
+\&\s-1UNIX\s0 domain sockets are not supported, \fInnrpd\fR\|(8) tries to hand off
+locally-posted articles through an \s-1INET\s0 domain socket to this server.
+\&\fIactsync\fR\|(8), \fInntpget\fR\|(8), and \fIgetlist\fR\|(8) also use this value as the default
+server to connect to. In the latter cases, the value of the \s-1NNTPSERVER\s0
+environment variable, if it exists, overrides this. The default value is
+unset.
+.Sh "Feed Configuration"
+.IX Subsection "Feed Configuration"
+These parameters govern incoming and outgoing feeds: what size of
+articles are accepted, what filtering and verification is performed on
+them, whether articles in groups not carried by the server are still
+stored and propagated, and other similar settings.
+.IP "\fIartcutoff\fR" 4
+.IX Item "artcutoff"
+Articles older than this number of days are dropped. This setting should
+probably match the setting on the \f(CW\*(C`/remember/\*(C'\fR line in \fIexpire.ctl\fR.
+The default value is \f(CW10\fR.
+.IP "\fIbindaddress\fR" 4
+.IX Item "bindaddress"
+Which \s-1IP\s0 address \fIinnd\fR\|(8) should bind itself to. This must be in
+dotted-quad format (nnn.nnn.nnn.nnn). If set to \f(CW\*(C`all\*(C'\fR or not set, innd
+defaults to listening on all interfaces. The value of the
+\&\s-1INND_BIND_ADDRESS\s0 environment variable, if set, overrides this setting.
+The default value is unset.
+.IP "\fIbindaddress6\fR" 4
+.IX Item "bindaddress6"
+Like \fIbindaddress\fR but for IPv6 sockets. If only one of the \fIbindaddress\fR
+and \fIbindaddress6\fR parameters is used, then only the socket for the
+corresponding address family is created. If both parameters are used
+then two sockets are created. If neither of them is used, the list of
+sockets to listen on will be determined by the system library
+\&\fI\fIgetaddrinfo\fI\|(3)\fR function. The value of the \s-1INND_BIND_ADDRESS6\s0, if set,
+overrides this setting. The default value is unset.
+.Sp
+Note that you will generally need to put double quotes ("") around this
+value if you set it, since IPv6 addresses contain colons.
+.IP "\fIhiscachesize\fR" 4
+.IX Item "hiscachesize"
+If set to a value other than \f(CW0\fR, a hash of recently received message IDs
+is kept in memory to speed history lookups. The value is the amount of
+memory to devote to the cache in kilobytes. The cache is only used for
+incoming feeds and a small cache can hold quite a few message IDs, so
+large values aren't necessarily useful unless you have incoming feeds that
+are badly delayed. A good value for a system with more than one incoming
+feed is \f(CW256\fR; systems with only one incoming feed should probably leave
+this at \f(CW0\fR. The default value is \f(CW0\fR.
+.IP "\fIignorenewsgroups\fR" 4
+.IX Item "ignorenewsgroups"
+Whether newsgroup creation control messages (newgroup and rmgroup) should
+be fed as if they were posted to the newsgroup they are creating or
+deleting rather than to the newsgroups listed in the Newsgroups: header.
+If this parameter is set, the newsgroup affected by the control message
+will be extracted from the Control: header and the article will be fed as
+if its Newsgroups: header contained solely that newsgroup. This is useful
+for routing control messages to peers when they are posted to irrelevant
+newsgroups that shouldn't be matched against the peer's desired newsgroups
+in \fInewsfeeds\fR. This is a boolean value and the default is false.
+.IP "\fIimmediatecancel\fR" 4
+.IX Item "immediatecancel"
+When using the timecaf storage method, article cancels are normally just
+cached to be cancelled, not cancelled immediately. If this is set to
+true, they will instead by cancelled as soon as the cancel is processed.
+This is a boolean value and the default is false.
+.Sp
+This setting is ignored unless the timecaf storage method is used.
+.IP "\fIlinecountfuzz\fR" 4
+.IX Item "linecountfuzz"
+If set to something other than \f(CW0\fR, the line count of the article is
+checked against the Lines: header of the article (if present) and the
+artice is rejected if the values differ by more than this amount. A
+reasonable setting is \f(CW5\fR, which is the standard maximum signature length
+plus one (some injection software calculates the Lines: header before
+adding the signature). The default value is \f(CW0\fR, which tells \s-1INN\s0 not to
+check the Lines: header of incoming articles.
+.IP "\fImaxartsize\fR" 4
+.IX Item "maxartsize"
+The maximum size of article (headers and body) that will be accepted by
+the server, in bytes. A value of \f(CW0\fR allows any size of article, but
+note that \fBinnd\fR will crash if system memory is exceeded. The default
+value is \f(CW1000000\fR (approximately 1 \s-1MB\s0). See also \fIlocalmaxartsize\fR.
+.IP "\fImaxconnections\fR" 4
+.IX Item "maxconnections"
+The maximum number of incoming \s-1NNTP\s0 connections \fIinnd\fR\|(8) will accept. The
+default value is \f(CW50\fR.
+.IP "\fIpathalias\fR" 4
+.IX Item "pathalias"
+If set, this value is prepended to the Path: header of accepted posts
+(before \fIpathhost\fR) if it doesn't already appear in the Path: header.
+The main purpose of this parameter is to configure all news servers within
+a particular organization to add a common identity string to the
+Path: header. The default value is unset.
+.IP "\fIpathcluster\fR" 4
+.IX Item "pathcluster"
+If set, this value is appended to the Path: header of accepted posts
+(after \fIpathhost\fR) if it isn't already present as the last element
+of the Path: header. The main purpose of this parameter is to make
+several news servers appear as one server. The default value is unset.
+.Sp
+Note that the Path: header reads right to left, so appended means inserted
+at the leftmost side of the Path: header.
+.IP "\fIpgpverify\fR" 4
+.IX Item "pgpverify"
+Whether to enable \s-1PGP\s0 verification of control messages other than cancel.
+This is a boolean value and the default is based on whether configure found
+pgp, pgpv, or gpgv.
+.IP "\fIport\fR" 4
+.IX Item "port"
+What \s-1TCP\s0 port \fIinnd\fR\|(8) should listen on. The default value is \f(CW119\fR, the
+standard \s-1NNTP\s0 port.
+.IP "\fIrefusecybercancels\fR" 4
+.IX Item "refusecybercancels"
+Whether to refuse all articles whose message IDs start with
+\&\f(CW\*(C`<cancel.\*(C'\fR. This message \s-1ID\s0 convention is widely followed by spam
+cancellers, so the vast majority of such articles will be cancels of spam.
+This check, if enabled, is done before the history check and the message
+\&\s-1ID\s0 is not written to the history file. This is a boolean value and the
+default is false.
+.Sp
+This is a somewhat messy, inefficient, and inexact way of refusing spam
+cancels. A much better way is to ask all of your upstream peers to not
+send to you any articles with \f(CW\*(C`cyberspam\*(C'\fR in the Path: header (usually
+accomplished by having them mark \f(CW\*(C`cyberspam\*(C'\fR as an alias for your machine
+in their feed configuration). The filtering enabled by this parameter is
+hard\-coded; general filtering of message IDs can be done via the embedded
+filtering support.
+.IP "\fIremembertrash\fR" 4
+.IX Item "remembertrash"
+By default, \fIinnd\fR\|(8) records rejected articles in history so that, if
+offered the same article again, it can be refused before it is sent. If
+you wish to disable this behavior, set this to false. This can cause a
+substantial increase in the amount of bandwidth consumed by incoming news
+if you have several peers and reject a lot of articles, so be careful with
+it. Even if this is set to true, \s-1INN\s0 won't log some rejected articles to
+history if there's reason to believe the article might be accepted if
+offered by a different peer, so there is usually no reason to set this to
+false (although doing so can decrease the size of the history file). This
+is a boolean value and the default is true.
+.IP "\fIsourceaddress\fR" 4
+.IX Item "sourceaddress"
+Which local \s-1IP\s0 address to bind to for outgoing \s-1NNTP\s0 sockets (used by
+\&\fIinnxmit\fR\|(8) among other programs, but \fInot\fR \fIinnfeed\fR\|(8) \*(-- see
+\&\fIbindaddress\fR in \fIinnfeed.conf\fR\|(5) for that). This must be in dotted-quad
+format (nnn.nnn.nnn.nnn). If set to \f(CW\*(C`all\*(C'\fR or not set, the operating
+system will choose the source \s-1IP\s0 address for outgoing connections. The
+default value is unset.
+.IP "\fIsourceaddress6\fR" 4
+.IX Item "sourceaddress6"
+Like \fIsourceaddress\fR but for IPv6 sockets.
+.IP "\fIverifycancels\fR" 4
+.IX Item "verifycancels"
+Set this to true to enable a simplistic check on all cancel messages,
+attempting to verify (by simple header comparison) that the cancel message
+is from the same person as the original post. This can't be done if the
+cancel arrives before the article does, and is extremely easy to spoof.
+While this check may once have served a purpose, it's now essentially
+security via obscurity, commonly avoided by abusers, and probably not
+useful. This is a boolean value, and the default is false.
+.IP "\fIwanttrash\fR" 4
+.IX Item "wanttrash"
+Set this to true if you want to file articles posted to unknown newsgroups
+(newsgroups not in the \fIactive\fR file) into the \f(CW\*(C`junk\*(C'\fR newsgroup rather
+than rejecting them. This is sometimes useful for a transit news server
+that needs to propagate articles in all newsgroups regardless if they're
+carried locally. This is a boolean value and the default is false.
+.IP "\fIwipcheck\fR" 4
+.IX Item "wipcheck"
+If \s-1INN\s0 is offered an article by a peer on one channel, it will return
+deferral responses (code 436) to all other offers of that article for this
+many seconds. (After this long, if the peer that offered the article
+still hasn't sent it, it will be accepted from other channels.) The
+default value is \f(CW5\fR and probably doesn't need to be changed.
+.IP "\fIwipexpire\fR" 4
+.IX Item "wipexpire"
+How long, in seconds, to keep track of message IDs offered on a channel
+before expiring articles that still haven't been sent. The default value
+is \f(CW10\fR and probably doesn't need to be changed.
+.IP "\fIdontrejectfiltered\fR" 4
+.IX Item "dontrejectfiltered"
+Normally \fIinnd\fR\|(8) rejects incoming articles when directed to do so by any
+enabled article filters (Perl, Python, and \s-1TCL\s0). However, this parameter
+causes such articles \fInot\fR to be rejected; instead filtering can be
+applied on outbound articles. If this parameter is set, all articles will
+be accepted on the local machine, but articles rejected by the filter will
+\&\fInot\fR be fed to any peers specified in \fInewsfeeds\fR with the \f(CW\*(C`Af\*(C'\fR flag.
+.Sh "Article Storage"
+.IX Subsection "Article Storage"
+These parameters affect how articles are stored on disk.
+.IP "\fIcnfscheckfudgesize\fR" 4
+.IX Item "cnfscheckfudgesize"
+If set to a value other than \f(CW0\fR, the claimed size of articles in \s-1CNFS\s0
+cycbuffs is checked against \fImaxartsize\fR plus this value, and if larger,
+the \s-1CNFS\s0 cycbuff is considered corrupt. This can be useful as a sanity
+check after a system crash, but be careful using this parameter if you
+have changed \fImaxartsize\fR recently. The default value is \f(CW0\fR.
+.IP "\fIenableoverview\fR" 4
+.IX Item "enableoverview"
+Whether to write out overview data for articles. If set to false, \s-1INN\s0
+will run much faster, but reading news from the system will be impossible
+(the server will be for news transit only). If this option is set to
+true, \fIovmethod\fR must also be set. This is a boolean value and the
+default is true.
+.IP "\fIgroupbaseexpiry\fR" 4
+.IX Item "groupbaseexpiry"
+Whether to enable newsgroup-based expiry. If set to false, article expiry
+is done based on storage class of storing method. If set to true (and
+overview information is available), expiry is done by newsgroup name.
+This affects the format of \fIexpire.ctl\fR. This is a boolean value and the
+default is true.
+.IP "\fImergetogroups\fR" 4
+.IX Item "mergetogroups"
+Whether to file all postings to \f(CW\*(C`to.*\*(C'\fR groups in the pseudonewsgroup
+\&\f(CW\*(C`to\*(C'\fR. If this is set to true, the newsgroup \f(CW\*(C`to\*(C'\fR must exist in the
+\&\fIactive\fR file or \s-1INN\s0 will not start. (See the discussion of \f(CW\*(C`to.\*(C'\fR
+groups in \fIinnd\fR\|(8) under \s-1CONTROL\s0 \s-1MESSAGES\s0.) This is a boolean value and
+the default is false.
+.IP "\fIovercachesize\fR" 4
+.IX Item "overcachesize"
+How many cache slots to reserve for open overview files. If \s-1INN\s0 is
+writing overview files (see \fIenableoverview\fR), \fIovmethod\fR is set to
+\&\f(CW\*(C`tradindexed\*(C'\fR, and this is set to a value other than \f(CW0\fR, \s-1INN\s0 will keep
+around and open that many recently written-to overview files in case more
+articles come in for those newsgroups. Every overview cache slot consumes
+two file descriptors, so be careful not to set this value too high. You
+may be able to use the \f(CW\*(C`limit\*(C'\fR command to see how many open file
+descriptors your operating system allows. \fIinnd\fR\|(8) also uses an open file
+descriptor for each incoming feed and outgoing channel or batch file, and
+if it runs out of open file descriptors it may throttle and stop accepting
+new news. The default value is \f(CW15\fR (which is probably way too low if
+you have a large number of file descriptors available).
+.Sp
+This setting is ignored unless \fIovmethod\fR is set to \f(CW\*(C`tradindexed\*(C'\fR.
+.IP "\fIovgrouppat\fR" 4
+.IX Item "ovgrouppat"
+If set, restricts the overview data stored by \s-1INN\s0 to only the newsgroups
+matching this comma-separated list of wildmat expressions. Newsgroups not
+matching this setting may not be readable, and if \fIgroupbaseexpiry\fR is
+set to true and the storage method for these newsgroups does not have
+self-expire functionality, storing overview data will fail.
+The default is unset.
+.IP "\fIovmethod\fR" 4
+.IX Item "ovmethod"
+Which overview storage method to use. Currently supported values are
+\&\f(CW\*(C`tradindexed\*(C'\fR, \f(CW\*(C`buffindexed\*(C'\fR, and \f(CW\*(C`ovdb\*(C'\fR. There is no default value;
+this parameter must be set if \fIenableoverview\fR is true (the default).
+.RS 4
+.ie n .IP """buffindexed""" 4
+.el .IP "\f(CWbuffindexed\fR" 4
+.IX Item "buffindexed"
+Stores overview data and index information into buffers, which are
+preconfigured files defined in \fIbuffinedexed.conf\fR. \f(CW\*(C`buffindexed\*(C'\fR never
+consumes additional disk space beyond that allocated to these buffers.
+.ie n .IP """tradindexed""" 4
+.el .IP "\f(CWtradindexed\fR" 4
+.IX Item "tradindexed"
+Uses two files per newsgroup, one containing the overview data and one
+containing the index. Fast for readers, but slow to write to.
+.ie n .IP """ovdb""" 4
+.el .IP "\f(CWovdb\fR" 4
+.IX Item "ovdb"
+Stores data into a Berkeley \s-1DB\s0 database. See the \fIovdb\fR\|(5) man page.
+.RE
+.RS 4
+.RE
+.IP "\fIhismethod\fR" 4
+.IX Item "hismethod"
+Which history storage method to use. The only currently supported
+value is \f(CW\*(C`hisv6\*(C'\fR. There is no default value; this parameter must
+be set.
+.RS 4
+.ie n .IP """hisv6""" 4
+.el .IP "\f(CWhisv6\fR" 4
+.IX Item "hisv6"
+Stores history data in the \s-1INN\s0 history v6 format: \fIhistory\fR\|(5) text
+file and a number of \fIdbz\fR\|(3) database files; this may be in true history
+v6 format, or tagged hash format, depending on the build
+options. Separation of these two is a project which has not yet been
+undertaken.
+.RE
+.RS 4
+.RE
+.IP "\fIstoreonxref\fR" 4
+.IX Item "storeonxref"
+If set to true, articles will be stored based on the newsgroup names in
+the Xref: header rather than in the Newsgroups: header. This affects what
+the patterns in \fIstorage.conf\fR apply to. The primary interesting effect
+of setting this to true is to enable filing of all control messages
+according to what storage class the control pseudogroups are filed in
+rather than according to the newsgroups the control messages are posted
+to. This is a boolean value and the default is true.
+.IP "\fIuseoverchan\fR" 4
+.IX Item "useoverchan"
+Whether to \fIinnd\fR\|(8) should create overview data internally through
+\&\fIlibstorage\fR\|(3). If set to false, innd creates overview data by itself. If
+set to true, innd does not create; instead overview data must be created
+by \fIoverchan\fR\|(8) from an appropriate entry in \fInewsfeeds\fR. Setting to true
+may be useful, if innd cannot keep up with incoming feed and the
+bottleneck is creation of overview data within innd. This is a boolean
+value and the default is false.
+.IP "\fIwireformat\fR" 4
+.IX Item "wireformat"
+Only used with the tradspool storage method, this says whether to write
+articles in wire format. Wire format means storing articles with \f(CW\*(C`\er\en\*(C'\fR at
+the end of each line and with periods at the beginning of lines doubled,
+the article format required by the \s-1NNTP\s0 protocol. Articles stored in this
+format are suitable for sending directly to a network connection without
+requiring conversion, and therefore setting this to true can make the
+server more efficient. The primary reason not to set this is if you have
+old existing software that looks around in the spool and doesn't
+understand how to read wire format. Storage methods other than tradspool
+always store articles in wire format. This is a boolean value and the
+default is false.
+.IP "\fIxrefslave\fR" 4
+.IX Item "xrefslave"
+Whether to act as the slave of another server. If set, \s-1INN\s0 attempts to
+duplicate exactly the article numbering of the server feeding it by
+looking at the Xref: header of incoming articles and assigning the same
+article numbers to articles as was noted in the Xref: header from the
+upstream server. The result is that clients should be able to point at
+either server interchangeably (using some load balancing scheme, for
+example) and see the same internal article numbering. Servers with this
+parameter set should generally only have one upstream feed, and should
+always have \fInnrpdposthost\fR set to hand locally posted articles off to
+the master server. The upstream should be careful to always feed articles
+in order (\fIinnfeed\fR\|(8) can have problems with this in the event of a
+backlog). This is a boolean value and the default is false.
+.IP "\fInfswriter\fR" 4
+.IX Item "nfswriter"
+For servers writing articles, determine whether the article spool is
+on \s-1NFS\s0 storage. If set, \s-1INN\s0 attempts to flush articles to the spool
+in a more timely manner, rather than relying on the operating system
+to flush things such as the \s-1CNFS\s0 article bitmaps. You should only set
+this parameter if you are attempting to use a shared \s-1NFS\s0 spool on a
+machine acting as a single writer within a cluster. This is a boolean
+value and the default is false.
+.IP "\fInfsreader\fR" 4
+.IX Item "nfsreader"
+For servers reading articles, determine whether the article spool is
+on \s-1NFS\s0 storage. If set, \s-1INN\s0 will attempt to force articles and
+overviews to be read directly from the \s-1NFS\s0 spool rather than from
+cached copies. You should only set this parameter if you are
+attempting to use a shared \s-1NFS\s0 spool on a machine acting a reader a
+cluster. This is a boolean value and the default is false.
+.IP "\fInfsreaderdelay\fR" 4
+.IX Item "nfsreaderdelay"
+For servers reading articles, determine whether the article spool is
+on \s-1NFS\s0 storage. If \fInfsreader\fR is set, \s-1INN\s0 will use the value of
+\&\fInfsreaderdelay\fR to delay the apparent arrival time of articles to
+clients by this amount; this value should be tuned based on the \s-1NFS\s0
+cache timeouts locally. This default is 60 (1 minute).
+.IP "\fImsgidcachesize\fR" 4
+.IX Item "msgidcachesize"
+How many cache slots to reserve for Message \s-1ID\s0 to storage token
+translations. When serving overview data to clients (\s-1NEWNEWS\s0, \s-1XOVER\s0
+etc.), \fInnrpd\fR\|(8) can cache the storage token associated with a Message
+\&\s-1ID\s0 and save the cost of looking it up in the history file; for some
+configurations setting this parameter can save more than 90% of the
+wall clock time for a session. The default value is 10000.
+.IP "\fItradindexedmmap\fR" 4
+.IX Item "tradindexedmmap"
+Whether to attempt to \fImmap()\fR tradindexed overviews articles. Setting
+this to true will give better performance on most systems, but some
+systems have problems with \fImmap()\fR. If this is set to false, overviews
+will be read into memory before being sent to readers. This is a
+boolean value and the default is true.
+.Sh "Reading"
+.IX Subsection "Reading"
+These parameters affect the behavior of \s-1INN\s0 for readers. Most of them are
+used by \fInnrpd\fR\|(8). There are some special sets of settings that are broken
+out separately after the initial alphabetized list.
+.IP "\fIallownewnews\fR" 4
+.IX Item "allownewnews"
+Whether to allow use of the \s-1NEWNEWS\s0 command by clients. This command used
+to put a heavy load on the server in older versions of \s-1INN\s0, but is now
+reasonably efficient, at least if only one newsgroup is specified by the
+client. This is a boolean value and the default is true. If you use the
+\&\fIaccess\fR parameter in \fIreaders.conf\fR, be sure to read about the way it
+overrides \fIallownewnews\fR.
+.IP "\fIarticlemmap\fR" 4
+.IX Item "articlemmap"
+Whether to attempt to \fImmap()\fR articles. Setting this to true will give
+better performance on most systems, but some systems have problems with
+\&\fImmap()\fR. If this is set to false, articles will be read into memory before
+being sent to readers. This is a boolean value and the default is false.
+.IP "\fIclienttimeout\fR" 4
+.IX Item "clienttimeout"
+How long (in seconds) a client connection can be idle before it exits.
+When setting this parameter, be aware that some newsreaders use the same
+connection for reading and posting and don't deal well with the connection
+timing out while a post is being composed. If the system isn't having a
+problem with too many long-lived connections, it may be a good idea to
+increase this value to \f(CW3600\fR (an hour). The default value is \f(CW600\fR
+(ten minutes).
+.IP "\fIinitialtimeout\fR" 4
+.IX Item "initialtimeout"
+How long (in seconds) \fBnnrpd\fR will wait for the first command from a
+reader connection before dropping the connection. This is a defensive
+timeout intended to protect the news server from badly behaved reader
+clients that open and abandon a multitude of connections without every
+closing them. The default value is \f(CW10\fR (ten seconds), which may need to
+be increased if many clients connect via slow network links.
+.IP "\fInnrpdcheckart\fR" 4
+.IX Item "nnrpdcheckart"
+Whether \fBnnrpd\fR should check the existence of an article before listing
+it as present in response to an \s-1NNTP\s0 command. The primary use of this
+setting is to prevent nnrpd from returning information about articles
+which are no longer present on the server but which still have overview
+data available. Checking the existence of articles before returning
+overview information slows down the overview commands, but reduces the
+number of \*(L"article is missing\*(R" errors seen by the client. This is a
+boolean value and the default is true.
+.IP "\fInnrpperlauth\fR" 4
+.IX Item "nnrpperlauth"
+This parameter is now obsolete; see \*(L"Changes to Perl Authentication
+Support for nnrpd\*(R" in \fIdoc/hook\-perl\fR.
+.IP "\fInnrppythonauth\fR" 4
+.IX Item "nnrppythonauth"
+This parameter is now obsolete; see \*(L"Changes to Python Authentication and
+Access Control Support for nnrpd\*(R" in \fIdoc/hook\-python\fR.
+.IP "\fInoreader\fR" 4
+.IX Item "noreader"
+Normally, \fIinnd\fR\|(8) will fork a copy of \fInnrpd\fR\|(8) for all incoming
+connections from hosts not listed in \fIincoming.conf\fR. If this parameter
+is set to true, those connections will instead be rejected with a 502
+error code. This should be set to true for a transit-only server that
+doesn't support readers, or if nnrpd is running in daemon mode or being
+started out of inetd. This is a boolean value and the default is false.
+.IP "\fIreaderswhenstopped\fR" 4
+.IX Item "readerswhenstopped"
+Whether to allow readers to connect even if the server is paused or
+throttled. This is only applicable if \fInnrpd\fR\|(8) is spawned from \fIinnd\fR\|(8)
+rather than run out of inetd or in daemon mode. This is a boolean value
+and the default is false.
+.IP "\fIreadertrack\fR" 4
+.IX Item "readertrack"
+Whether to enable the tracking system for client behavior. Tracked
+information is recorded to \fIpathlog\fR/tracklogs/log\-ID, where \s-1ID\s0 is
+determined by nnrpd's \s-1PID\s0 and launch time.) Currently the information
+recorded includes initial connection and posting; only information about
+clients listed in \fInnrpd.track\fR is recorded. This is a boolean value and
+the default is false.
+.IP "\fInnrpdflags\fR" 4
+.IX Item "nnrpdflags"
+When \fInnrpd\fR\|(8) is spawned from \fIinnd\fR\|(8), these flags are passed as
+arguments to the nnrpd process. This setting does not affect instances
+of nnrpd that are started in daemon mode, or instances that are started
+via another listener process such as \fIinetd\fR\|(8) or \fIxinetd\fR\|(8). Shell
+quoting and metacharacters are not supported. This is a string value
+and the default is unset.
+.IP "\fInnrpdloadlimit\fR" 4
+.IX Item "nnrpdloadlimit"
+If set to a value other than \f(CW0\fR, connections to nnrpd will be refused
+if the system load average is higher than this value. The default value
+is \f(CW16\fR.
+.PP
+\&\s-1INN\s0 has optional support for generating keyword information automatically
+from article body text and putting that information in overview for the
+use of clients that know to look for it. The following parameters control
+that feature.
+.PP
+This may be too slow if you're taking a substantial feed, and probably
+will not be useful for the average news reader; enabling this is not
+recommended unless you have some specific intention to take advantage of
+it.
+.IP "\fIkeywords\fR" 4
+.IX Item "keywords"
+Whether the keyword generation support should be enabled. This is a
+boolean value and the default is false.
+.Sp
+\&\s-1FIXME:\s0 Currently, support for keyword generation is configured into \s-1INN\s0
+semi-randomly (based on whether configure found the regex library); it
+should be an option to configure and that option should be mentioned here.
+.IP "\fIkeyartlimit\fR" 4
+.IX Item "keyartlimit"
+Articles larger than this value in bytes will not have keywords generated
+for them (since it would take too long to do so). The default value is
+\&\f(CW100000\fR (approximately 100 \s-1KB\s0).
+.IP "\fIkeylimit\fR" 4
+.IX Item "keylimit"
+Maximum number of bytes allocated for keyword data. If there are more
+keywords than will fit into this many bytes when separated by commas, the
+rest are discarded. The default value is \f(CW512\fR.
+.IP "\fIkeymaxwords\fR" 4
+.IX Item "keymaxwords"
+Maximum number of keywords that will be generated for an article. (The
+keyword generation code will attempt to discard \*(L"noise\*(R" words, so the
+number of keywords actually writen into the overview will usually be
+smaller than this even if the maximum number of keywords is found.) The
+default value is \f(CW250\fR.
+.Sh "Posting"
+.IX Subsection "Posting"
+These parameters are only used by \fInnrpd\fR\|(8), \fIinews\fR\|(1), and other programs
+that accept or generate postings. There are some special sets of settings
+that are broken out separately after the initial alphabetized list.
+.IP "\fIaddnntppostingdate\fR" 4
+.IX Item "addnntppostingdate"
+Whether to add an NNTP\-Posting\-Date: header to all local posts. This is a
+boolean value and the default is true. Note that \s-1INN\s0 either does not add
+this header or adds the name or \s-1IP\s0 address of the client. There is no
+intrinsic support for obfuscating the name of the client. That has to be
+done with a user-written Perl filter, if desired.
+.IP "\fIaddnntppostinghost\fR" 4
+.IX Item "addnntppostinghost"
+Whether to add an NNTP\-Posting\-Host: header to all local posts giving the
+\&\s-1FQDN\s0 or \s-1IP\s0 address of the system from which the post was received. This
+is a boolean value and the default is true.
+.IP "\fIcheckincludedtext\fR" 4
+.IX Item "checkincludedtext"
+Whether to check local postings for the ratio of new to quoted text and
+reject them if that ratio is under 50%. Included text is recognized by
+looking for lines beginning with \f(CW\*(C`>\*(C'\fR, \f(CW\*(C`|\*(C'\fR, or \f(CW\*(C`:\*(C'\fR. This is a
+boolean value and the default is false.
+.IP "\fIcomplaints\fR" 4
+.IX Item "complaints"
+The value of the X\-Complaints\-To: header added to all local posts. The
+default is the newsmaster's e\-mail address. (If the newsmaster, selected
+at configure time and defaulting to \f(CW\*(C`usenet\*(C'\fR, doesn't contain \f(CW\*(C`@\*(C'\fR, the
+address will consist of the newsmaster, a \f(CW\*(C`@\*(C'\fR, and the value of
+\&\fIfromhost\fR.)
+.IP "\fIfromhost\fR" 4
+.IX Item "fromhost"
+Contains a domain used to construct e\-mail addresses. The address of the
+local news administrator will be given as <user>@\fIfromhost\fR, where <user>
+is the newsmaster user set at compile time (\f(CW\*(C`usenet\*(C'\fR by default). This
+setting will also be used by \fImailpost\fR\|(8) to fully qualify addresses and by
+\&\fIinews\fR\|(1) to generate the Sender: header (and From: header if missing).
+The value of the \s-1FROMHOST\s0 environment variable, if set, overrides this
+setting. The default is the fully-qualified domain name of the local
+host.
+.IP "\fIlocalmaxartsize\fR" 4
+.IX Item "localmaxartsize"
+The maximum article size (in bytes) for locally posted articles. Articles
+larger than this will be rejected. A value of \f(CW0\fR allows any size of
+article, but note that \fBnnrpd\fR and \fBinnd\fR will crash if system memory is
+exceeded. See also \fImaxartsize\fR, which applies to all articles including
+those posted locally. The default value is \f(CW1000000\fR (approximately 1
+\&\s-1MB\s0).
+.IP "\fImoderatormailer\fR" 4
+.IX Item "moderatormailer"
+The address to which to send submissions for moderated groups. It is only
+used if the \fImoderators\fR file doesn't exist, or if the moderated group to
+which an article is posted is not matched by any entry in that file, and
+takes the same form as an entry in the \fImoderators\fR file. In most cases,
+\&\f(CW\*(C`%s@moderators.isc.org\*(C'\fR is a good value for this parameter (\f(CW%s\fR is
+expanded into a form of the newsgroup name). See \fImoderators\fR\|(5) for more
+details about the syntax. The default is unset. If this parameter isn't
+set and an article is posted to a moderated group that does not have a
+matching entry in the \fImoderators\fR file, the posting will be rejected
+with an error.
+.IP "\fInnrpdauthsender\fR" 4
+.IX Item "nnrpdauthsender"
+Whether to generate a Sender: header based on reader authentication. If
+this parameter is set, a Sender: header will be added to local posts
+containing the identity assigned by \fIreaders.conf\fR. If the assigned
+identity does not include an \f(CW\*(C`@\*(C'\fR, the reader's hostname is used. If this
+parameter is set but no identity is be assigned, the Sender: header will
+be removed from all posts even if the poster includes one. This is a
+boolean value and the default is false.
+.IP "\fInnrpdposthost\fR" 4
+.IX Item "nnrpdposthost"
+If set, \fInnrpd\fR\|(8) and \fIrnews\fR\|(1) will pass all locally posted articles to the
+specified host rather than trying to inject them locally. See also
+\&\fInnrpdpostport\fR. This should always be set if \fIxrefslave\fR is true. The
+default value is unset.
+.IP "\fInnrpdpostport\fR" 4
+.IX Item "nnrpdpostport"
+The port on the remote server to connect to to post when \fInnrpdposthost\fR
+is used. The default value is \f(CW119\fR.
+.IP "\fIorganization\fR" 4
+.IX Item "organization"
+What to put in the Organization: header if it is left blank by the poster.
+The value of the \s-1ORGANIZATION\s0 environment variable, if set, overrides this
+setting. The default is unset, which tells \s-1INN\s0 not to insert an
+Organization: header.
+.IP "\fIspoolfirst\fR" 4
+.IX Item "spoolfirst"
+If true, \fInnrpd\fR\|(8) will spool new articles rather than attempting to send
+them to \fIinnd\fR\|(8). If false, nnrpd will spool articles only if it receives
+an error trying to send them to innd. Setting this to true can be useful
+if nnrpd must respond as fast as possible to the client; however, when
+set, articles will not appear to readers until they are given to innd.
+nnrpd won't do this; \f(CW\*(C`rnews \-U\*(C'\fR must be run periodically to take the
+spooled articles and post them. This is a boolean value and the default
+is false.
+.IP "\fIstrippostcc\fR" 4
+.IX Item "strippostcc"
+Whether to strip To:, Cc:, and Bcc: headers out of all local posts via
+\&\fInnrpd\fR\|(8). The primary purpose of this setting is to prevent abuse of the
+news server by posting to a moderated group and including To: or Cc:
+headers in the post so that the news server will send the article to
+arbitrary addresses. \s-1INN\s0 now protects against this abuse in other ways
+provided \fImta\fR is set to a command that includes \f(CW%s\fR and honors it, so
+this is generally no longer needed. This is a boolean value and the
+default is false.
+.PP
+\&\fInnrpd\fR\|(8) has support for controlling high-volume posters via an
+exponential backoff algorithm, as configured by the following parameters.
+.PP
+Exponential posting backoff works as follows: News clients are indexed by
+\&\s-1IP\s0 address (or username, see \fIbackoffauth\fR below). Each time a post is
+received from an \s-1IP\s0 address, the time of posting is stored (along with the
+previous sleep time, see below). After a configurable number of posts in
+a configurable period of time, \fInnrpd\fR\|(8) will activate posting backoff and
+begin to sleep for increasing periods of time before actually posting
+anything. Posts will still be accepted, but at an increasingly reduced
+rate.
+.PP
+After backoff has been activated, the length of time to sleep is computed
+based on the difference in time between the last posting and the current
+posting. If this difference is less than \fIbackoffpostfast\fR, the new
+sleep time will be 1 + (previous sleep time * \fIbackoffk\fR). If this
+difference is less than \fIbackoffpostslow\fR but greater than
+\&\fIbackoffpostfast\fR, then the new sleep time will equal the previous sleep
+time. If this difference is greater than \fIbackoffpostslow\fR, the new
+sleep time is zero and posting backoff is deactivated for this poster.
+.PP
+Exponential posting backoff will not be enabled unless \fIbackoffdb\fR is set
+and \fIbackoffpostfast\fR and \fIbackoffpostslow\fR are set to something other
+than their default values.
+.PP
+Here are the parameters that control exponential posting backoff:
+.IP "\fIbackoffauth\fR" 4
+.IX Item "backoffauth"
+Whether to index posting backoffs by user rather than by source \s-1IP\s0
+address. You must be using authentication in \fInnrpd\fR\|(8) for a value of true
+to have any meaning. This is a boolean value and the default is false.
+.IP "\fIbackoffdb\fR" 4
+.IX Item "backoffdb"
+The path to a directory, writeable by the news user, that will contain the
+backoff database. There is no default for this parameter; you must
+provide a path to a creatable or writeable directory to enable exponential
+backoff.
+.IP "\fIbackoffk\fR" 4
+.IX Item "backoffk"
+The amount to multiply the previous sleep time by if the user is still
+posting too quickly. A value of \f(CW2\fR will double the sleep time for each
+excessive post. The default value is \f(CW1\fR.
+.IP "\fIbackoffpostfast\fR" 4
+.IX Item "backoffpostfast"
+Postings from the same identity that arrive in less than this amount of
+time (in seconds) will trigger increasing sleep time in the backoff
+algorithm. The default value is \f(CW0\fR.
+.IP "\fIbackoffpostslow\fR" 4
+.IX Item "backoffpostslow"
+Postings from the same identity that arrive in greater than this amount of
+time (in seconds) will reset the backoff algorithm. Another way to look
+at this constant is to realize that posters will be allowed to generate at
+most 86400/\fIbackoffpostslow\fR posts per day. The default value is \f(CW1\fR.
+.IP "\fIbackofftrigger\fR" 4
+.IX Item "backofftrigger"
+This many postings are allowed before the backoff algorithm is triggered.
+The default value is \f(CW10000\fR.
+.Sh "Monitoring"
+.IX Subsection "Monitoring"
+These parameters control the behavior of \fIinnwatch\fR\|(8), the program that
+monitors \s-1INN\s0 and informs the news administrator if anything goes wrong
+with it.
+.IP "\fIdoinnwatch\fR" 4
+.IX Item "doinnwatch"
+Whether to start \fIinnwatch\fR\|(8) from rc.news. This is a boolean value, and
+the default is true.
+.IP "\fIinnwatchbatchspace\fR" 4
+.IX Item "innwatchbatchspace"
+Free space in \fIpathoutgoing\fR, in \fIinndf\fR\|(8) output units (normally
+kilobytes), at which \fIinnd\fR\|(8) will be throttled by \fIinnwatch\fR\|(8), assuming a
+default \fIinnwatch.ctl\fR. The default value is \f(CW800\fR.
+.IP "\fIinnwatchlibspace\fR" 4
+.IX Item "innwatchlibspace"
+Free space in \fIpathdb\fR, in \fIinndf\fR\|(8) output units (normally kilobytes), at
+which \fIinnd\fR\|(8) will be throttled by \fIinnwatch\fR\|(8), assuming a default
+\&\fIinnwatch.ctl\fR. The default value is \f(CW25000\fR.
+.IP "\fIinnwatchloload\fR" 4
+.IX Item "innwatchloload"
+Load average times 100 at which \fIinnd\fR\|(8) will be restarted by \fIinnwatch\fR\|(8)
+(undoing a previous pause or throttle), assuming a default
+\&\fIinnwatch.ctl\fR. The default value is \f(CW1000\fR (that is, a load average of
+10.00).
+.IP "\fIinnwatchhiload\fR" 4
+.IX Item "innwatchhiload"
+Load average times 100 at which \fIinnd\fR\|(8) will be throttled by \fIinnwatch\fR\|(8),
+assuming a default \fIinnwatch.ctl\fR. The default value is \f(CW2000\fR (that
+is, a load average of 20.00).
+.IP "\fIinnwatchpauseload\fR" 4
+.IX Item "innwatchpauseload"
+Load average times 100 at which \fIinnd\fR\|(8) will be paused by \fIinnwatch\fR\|(8),
+assuming a default \fIinnwatch.ctl\fR. The default value is \f(CW1500\fR (that
+is, a load average of 15.00).
+.IP "\fIinnwatchsleeptime\fR" 4
+.IX Item "innwatchsleeptime"
+How long (in seconds) \fIinnwatch\fR\|(8) will sleep between each check of \s-1INN\s0.
+The default value is \f(CW600\fR.
+.IP "\fIinnwatchspoolnodes\fR" 4
+.IX Item "innwatchspoolnodes"
+Free inodes in \fIpatharticles\fR at which \fIinnd\fR\|(8) will be throttled by
+\&\fIinnwatch\fR\|(8), assuming a default \fIinnwatch.ctl\fR. The default value is
+\&\f(CW200\fR.
+.IP "\fIinnwatchspoolspace\fR" 4
+.IX Item "innwatchspoolspace"
+Free space in \fIpatharticles\fR and \fIpathoverview\fR, in \fIinndf\fR\|(8) output
+units (normally kilobytes), at which \fIinnd\fR\|(8) will be throttled by
+\&\fIinnwatch\fR\|(8), assuming a default \fIinnwatch.ctl\fR. The default value is
+\&\f(CW8000\fR.
+.Sh "Logging"
+.IX Subsection "Logging"
+These parameters control what information \s-1INN\s0 logs.
+.IP "\fIdocnfsstat\fR" 4
+.IX Item "docnfsstat"
+Whether to start \fIcnfsstat\fR\|(8) when \fIinnd\fR\|(8) is started. cnfsstat will log
+the status of all \s-1CNFS\s0 cycbuffs to syslog on a periodic basis (frequency
+is the default for \f(CW\*(C`cnfsstat \-l\*(C'\fR, currently 600 seconds). This is a
+boolean value and the default is false.
+.IP "\fIlogartsize\fR" 4
+.IX Item "logartsize"
+Whether the size of accepted articles (in bytes) should be written to the
+article log file. This is useful for flow rate statistics and is
+recommended. This is a boolean value and the default is true.
+.IP "\fIlogcancelcomm\fR" 4
+.IX Item "logcancelcomm"
+Set this to true to log \f(CW\*(C`ctlinnd cancel\*(C'\fR commands to syslog. This is a
+boolean value and the default is false.
+.IP "\fIlogcycles\fR" 4
+.IX Item "logcycles"
+How many old logs \fIscanlogs\fR\|(8) keeps. \fIscanlogs\fR\|(8) is generally run by
+\&\fInews.daily\fR\|(8) and will archive compressed copies of this many days worth
+of old logs. The default value is \f(CW3\fR.
+.IP "\fIlogipaddr\fR" 4
+.IX Item "logipaddr"
+Whether the verified name of the remote feeding host should be logged to
+the article log for incoming articles rather than the last entry in the
+Path: header. The only reason to ever set this to false is due to some
+interactions with \fInewsfeeds\fR flags; see \fInewsfeeds\fR\|(5) for more
+information. This is a boolean value and the default is true.
+.IP "\fIlogsitename\fR" 4
+.IX Item "logsitename"
+Whether the names of the sites to which accepted articles will be sent
+should be put into the article log file. This is useful for debugging and
+statistics and can be used by \fInewsrequeue\fR\|(8). This is a boolean value and
+the default is true.
+.IP "\fInnrpdoverstats\fR" 4
+.IX Item "nnrpdoverstats"
+Whether nnrpd overview statistics should be logged via syslog. This can
+be useful for measuring overview performance. This is a boolean value and
+the default is false.
+.IP "\fInntpactsync\fR" 4
+.IX Item "nntpactsync"
+How many articles to process on an incoming channel before logging the
+activity. The default value is \f(CW200\fR.
+.Sp
+\&\s-1FIXME:\s0 This is a rather unintuitive name for this parameter.
+.IP "\fInntplinklog\fR" 4
+.IX Item "nntplinklog"
+Whether to put the storage \s-1API\s0 token for accepted articles (used by
+nntplink) in the article log. This is a boolean value and the default is
+false.
+.IP "\fIstathist\fR" 4
+.IX Item "stathist"
+Where to write history statistics for analysis with
+\&\fIcontrib/stathist.pl\fR; this can be modified with \fIctlinnd\fR\|(8) while innd is
+running. Logging does not occur unless a path is given, and there is no
+default value.
+.IP "\fIstatus\fR" 4
+.IX Item "status"
+How frequently (in seconds) \fIinnd\fR\|(8) should write out a status report. The
+report is written to \fIpathhttp\fR/inn_status.html. If this is set to \f(CW0\fR or
+\&\f(CW\*(C`false\*(C'\fR, status reporting is disabled. The default value is \f(CW0\fR.
+.IP "\fItimer\fR" 4
+.IX Item "timer"
+How frequently (in seconds) \fIinnd\fR\|(8) should report performance timings to
+syslog. If this is set to \f(CW0\fR, performance timing is disabled. Enabling
+this is highly recommended, and \fIinnreport\fR\|(8) can produce a nice summary of
+the timings. If set to \f(CW0\fR, performance timings in \fInnrpd\fR\|(8) are also
+disabled, although nnrpd always reports statistics on exit and therefore
+any non-zero value is equivalent for it. The default value is \f(CW0\fR.
+.Sh "System Tuning"
+.IX Subsection "System Tuning"
+The following parameters can be modified to tune the low-level operation
+of \s-1INN\s0. In general, you shouldn't need to modify any of them except
+possibly \fIrlimitnofile\fR unless the server is having difficulty.
+.IP "\fIbadiocount\fR" 4
+.IX Item "badiocount"
+How many read or write failures until a channel is put to sleep or
+closed. The default value is \f(CW5\fR.
+.IP "\fIblockbackoff\fR" 4
+.IX Item "blockbackoff"
+Each time an attempted write returns \s-1EAGAIN\s0 or \s-1EWOULDBLOCK\s0, \fIinnd\fR\|(8) will
+wait for an increasing number of seconds before trying it again. This is
+the multiplier for the sleep time. If you're having trouble with channel
+feeds not keeping up, it may be good to change this value to \f(CW2\fR or \f(CW3\fR,
+since then when the channel fills \s-1INN\s0 will try again in a couple of
+seconds rather than waiting two minutes. The default value is \f(CW120\fR.
+.IP "\fIchaninacttime\fR" 4
+.IX Item "chaninacttime"
+The time (in seconds) to wait between noticing inactive channels. The
+default value is \f(CW600\fR.
+.IP "\fIchanretrytime\fR" 4
+.IX Item "chanretrytime"
+How many seconds to wait before a channel restarts. The default value is
+\&\f(CW300\fR.
+.IP "\fIdatamovethreshold\fR" 4
+.IX Item "datamovethreshold"
+The threshold for deciding whether to move already-read data to the top of
+buffer or extend the buffer. The buffer described here is used for reading
+\&\s-1NNTP\s0 data. Increasing this value may improve performance, but it should
+not be increased on Systems with insufficient memory. Permitted values
+are between \f(CW0\fR and \f(CW1048576\fR (out of range values are treated as
+\&\f(CW1048576\fR) and the default value is \f(CW8192\fR.
+.IP "\fIicdsynccount\fR" 4
+.IX Item "icdsynccount"
+How many article writes between updating the active and history files.
+The default value is \f(CW10\fR.
+.IP "\fIkeepmmappedthreshold\fR" 4
+.IX Item "keepmmappedthreshold"
+When using buffindexed, retrieving overview data (that is, responding to
+\&\s-1XOVER\s0 or running expireover) causes mmapping of all overview data blocks
+which include requested overview data for newsgroup. But for high volume
+newsgroups like control.cancel, this may cause too much mmapping at once
+leading to system resource problems. To avoid this, if the amount to be
+mmapped exceeds \fIkeepmmappedthreshold\fR (in \s-1KB\s0), buffindexed mmap's just
+one overview block (8 \s-1KB\s0). This parameter is specific to buffindexed
+overview storage method. The default value is \f(CW1024\fR (1 \s-1MB\s0).
+.IP "\fImaxcmdreadsize\fR" 4
+.IX Item "maxcmdreadsize"
+If set to anything other than \f(CW0\fR, maximum buffer size (in bytes) for
+reading \s-1NNTP\s0 command will have this value. It should not be large on
+systems which are slow to process and store articles, as that would lead
+to \fIinnd\fR\|(8) spending a long time on each channel and keeping other channels
+waiting. The default value is \s-1BUFSIZ\s0 defined in stdio.h (\f(CW1024\fR in most
+environments, see \fIsetbuf\fR\|(3)).
+.IP "\fImaxforks\fR" 4
+.IX Item "maxforks"
+How many times to attempt a \fIfork\fR\|(2) before giving up. The default value
+is \f(CW10\fR.
+.IP "\fInicekids\fR" 4
+.IX Item "nicekids"
+If set to anything other than \f(CW0\fR, all child processes of \fIinnd\fR\|(8) will
+have this \fInice\fR\|(2) value. This is usually used to give all child processes
+of \fIinnd\fR\|(8) a lower priority (higher nice value) so that \fIinnd\fR\|(8) can get
+the lion's share of the \s-1CPU\s0 when it needs it. The default value is \f(CW4\fR.
+.IP "\fInicenewnews\fR" 4
+.IX Item "nicenewnews"
+If set to anything greater than \f(CW0\fR, all \fInnrpd\fR\|(8) processes that receive
+and process a \s-1NEWNEWS\s0 command will \fInice\fR\|(2) themselves to this value
+(giving other nnrpd processes a higher priority). The default value is
+\&\f(CW0\fR. Note that this value will be ignored if set to a lower value than
+\&\fInicennrpd\fR (or \fInicekids\fR if \fInnrpd\fR\|(8) is spawned from \fIinnd\fR\|(8)).
+.IP "\fInicennrpd\fR" 4
+.IX Item "nicennrpd"
+If set to anything greater than \f(CW0\fR, all \fInnrpd\fR\|(8) processes will \fInice\fR\|(1)
+themselves to this value. This gives other news processes a higher
+priority and can help \fIoverchan\fR\|(8) keep up with incoming news (if that's
+the object, be sure \fIoverchan\fR\|(8) isn't also set to a lower priority via
+\&\fInicekids\fR). The default value is \f(CW0\fR, which will cause \fInnrpd\fR\|(8)
+processes spawned from \fIinnd\fR\|(8) to use the value of \fInicekids\fR, while
+\&\fInnrpd\fR\|(8) run as a daemon will use the system default priority. Note that
+for \fInnrpd\fR\|(8) processes spawned from \fIinnd\fR\|(8), this value will be ignored if
+set to a value lower than \fInicekids\fR.
+.IP "\fIpauseretrytime\fR" 4
+.IX Item "pauseretrytime"
+Wait for this many seconds before noticing inactive channels.
+Wait for this many seconds before innd processes articles when it's paused
+or the number of channel write failures exceeds \fIbadiocount\fR. The
+default value is \f(CW300\fR.
+.IP "\fIpeertimeout\fR" 4
+.IX Item "peertimeout"
+How long (in seconds) an \fIinnd\fR\|(8) incoming channel may be inactive before
+innd closes it. The default value is \f(CW3600\fR (an hour).
+.IP "\fIrlimitnofile\fR" 4
+.IX Item "rlimitnofile"
+The maximum number of file descriptors that \fIinnd\fR\|(8) or \fIinnfeed\fR\|(8) can have
+open at once. If \fIinnd\fR\|(8) or \fIinnfeed\fR\|(8) attempts to open more file
+descriptors than this value, it is possible the program may throttle or
+otherwise suffer reduced functionality. The number of open file
+descriptors is roughly the maximum number of incoming feeds and outgoing
+batches for \fIinnd\fR\|(8) and the number of outgoing streams for \fIinnfeed\fR\|(8). If
+this parameter is set to a negative value, the default limit of the
+operating system will be used; this will normally be adequate on systems
+other than Solaris. Nearly all operating systems have some hard maximum
+limit beyond which this value cannot be raised, usually either 128, 256,
+or 1024. The default value of this parameter is \f(CW\*(C`\-1\*(C'\fR. Setting it to
+\&\f(CW256\fR on Solaris systems is highly recommended.
+.Sh "Paths and File Names"
+.IX Subsection "Paths and File Names"
+.IP "\fIpatharchive\fR" 4
+.IX Item "patharchive"
+Where to store archived news. The default value is \fIpathspool\fR/archive.
+.IP "\fIpatharticles\fR" 4
+.IX Item "patharticles"
+The path to where the news articles are stored (for storage methods other
+than \s-1CNFS\s0). The default value is \fIpathspool\fR/articles.
+.IP "\fIpathbin\fR" 4
+.IX Item "pathbin"
+The path to the news binaries. The default value is \fIpathnews\fR/bin.
+.IP "\fIpathcontrol\fR" 4
+.IX Item "pathcontrol"
+The path to the files that handle control messages. The code for handling
+each separate type of control message is located here. Be very careful
+what you put in this directory with a name ending in \f(CW\*(C`.pl\*(C'\fR, as it can
+potentially be a severe security risk. The default value is
+\&\fIpathbin\fR/control.
+.IP "\fIpathdb\fR" 4
+.IX Item "pathdb"
+The path to the database files used and updated by the server (currently,
+\&\fIactive\fR, \fIactive.times\fR, \fIhistory\fR and its indices, and
+\&\fInewsgroups\fR). The default value is \fIpathnews\fR/db.
+.IP "\fIpathetc\fR" 4
+.IX Item "pathetc"
+The path to the news configuration files. The default value is
+\&\fIpathnews\fR/etc.
+.IP "\fIpathfilter\fR" 4
+.IX Item "pathfilter"
+The path to the Perl, Tcl, and Python filters. The default value is
+\&\fIpathbin\fR/filter.
+.IP "\fIpathhttp\fR" 4
+.IX Item "pathhttp"
+Where any \s-1HTML\s0 files (such as periodic status reports) are placed. If the
+news reports should be available in real-time on the web, the files in
+this directory should be served by a web server. The default value is
+the value of \fIpathlog\fR.
+.IP "\fIpathincoming\fR" 4
+.IX Item "pathincoming"
+Location where incoming batched news is stored. The default value is
+\&\fIpathspool\fR/incoming.
+.IP "\fIpathlog\fR" 4
+.IX Item "pathlog"
+Where the news log files are written. The default value is
+\&\fIpathnews\fR/log.
+.IP "\fIpathnews\fR" 4
+.IX Item "pathnews"
+The home directory of the news user and usually the root of the news
+hierarchy. There is no default; this parameter must be set in \fIinn.conf\fR
+or \s-1INN\s0 will refuse to start.
+.IP "\fIpathoutgoing\fR" 4
+.IX Item "pathoutgoing"
+Default location for outgoing feed files. The default value is
+\&\fIpathspool\fR/outgoing.
+.IP "\fIpathoverview\fR" 4
+.IX Item "pathoverview"
+The path to news overview files. The default value is
+\&\fIpathspool\fR/overview.
+.IP "\fIpathrun\fR" 4
+.IX Item "pathrun"
+The path to files required while the server is running and run-time state
+information. This includes lock files and the sockets for communicating
+with \fIinnd\fR\|(8). This directory and the control sockets in it should be
+protected from unprivileged users other than the news user. The default
+value is \fIpathnews\fR/run.
+.IP "\fIpathspool\fR" 4
+.IX Item "pathspool"
+The root of the news spool hierarchy. This used mostly to set the
+defaults for other parameters, and to determine the path to the backlog
+directory for \fIinnfeed\fR\|(8). The default value is \fIpathnews\fR/spool.
+.IP "\fIpathtmp\fR" 4
+.IX Item "pathtmp"
+Where \s-1INN\s0 puts temporary files. For security reasons, this is not the
+same as the system temporary files directory (\s-1INN\s0 creates a lot of
+temporary files with predictable names and does not go to particularly
+great lengths to protect against symlink attacks and the like; this
+is safe provided that normal users can't write into its temporary
+directory). The default value is set at configure time and defaults to
+\&\fIpathnews\fR/tmp.
+.SH "EXAMPLE"
+.IX Header "EXAMPLE"
+Here is a very minimalist example that only sets those parameters that are
+required.
+.PP
+.Vb 5
+\& mta: /usr/lib/sendmail \-oi \-oem %s
+\& ovmethod: tradindexed
+\& pathhost: news.example.com
+\& pathnews: /usr/local/news
+\& hismethod: hisv6
+.Ve
+.PP
+For a more comprehensive example, see the sample \fIinn.conf\fR distributed
+with \s-1INN\s0 and installed as a starting point; it contains all of the default
+values for reference.
+.SH "HISTORY"
+.IX Header "HISTORY"
+Written by Rich \f(CW$alz\fR <rsalz@uunet.uu.net> for InterNetNews and since
+modified, updated, and reorganized by innumerable other people.
+.PP
+$Id: inn.conf.5 7880 2008-06-16 20:37:13Z iulius $
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIinews\fR\|(1), \fIinnd\fR\|(8), \fIinnwatch\fR\|(8), \fInnrpd\fR\|(8), \fIrnews\fR\|(1).
+.PP
+Nearly every program in \s-1INN\s0 uses this file to one degree or another. The
+above are just the major and most frequently mentioned ones.
--- /dev/null
+##########################################################
+# Configuration file for innreport (3.*).
+#
+# Sample file for INN.
+# Tested with INN 2.3, 2.1, 1.7.2 and 1.5.1.
+#
+# (c) 1997, 1998, 1999 by Fabien Tassin <fta@sofaraway.org>
+# version 3.0.2
+##########################################################
+
+# Default parameters
+section default {
+ libpath "@LIBDIR@";
+ logpath "@LOGDIR@";
+ unknown true; # want unknown entries.
+ max_unknown 50; # max unknown entries to display.
+ casesensitive true;
+ module "innreport_inn"; # ${libpath}/${module}.pm
+ unwanted_log "unwanted.log"; # ${logpath}/${unwanted_log}
+ text true;
+ html false;
+ graph true; # need 'html'
+ archive true; # use false to keep only the latest HTML report.
+ index "index.html"; # name of the HTML index file.
+ # html_dir "/var/www/News/stats"; # default to pathhttp in inn.conf
+ img_dir "pics"; # images will go to ${html_dir}/${img_dir}
+ cycle none; # use a number or 'none'.
+ separator "."; # use a valid filename character.
+ title "Daily Usenet report";
+ # title "Daily Usenet report for <A HREF=\"/News/stats/\">news.y.z</A>";
+ # footer "Local contact: <A HREF=\"mailto:x@y.z\">x@y.z</A>";
+ # html_body "BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\"";
+ # html_header_file "header.html"; # ${html_dir}/${html_header_file}
+ # html_footer_file "footer.html"; # ${html_dir}/${html_footer_file}
+ graph_width 550; # graph width (in pixels)
+ transparent true; # graph background transparent ?
+ graph_fg "#000000"; # graph foreground color.
+ graph_bg "#FFFFFF"; # graph background color.
+};
+
+###########################################################################
+# Index page
+section index {
+ column {
+ title "Dates";
+ value "date";
+ };
+ column {
+ title "Incoming feeds";
+ name "Offered|Accepted|Volume";
+ value "total(%innd_offered) | total(%innd_accepted) |
+ bytes(total(%inn_flow_size))";
+ };
+ column {
+ title "Outgoing feeds";
+ name "Offered|Accepted|Volume";
+ value "total(%innfeed_offered) + total(%nntplink_offered) +
+ total(%innxmit_offered) | total(%innfeed_accepted) +
+ total(%nntplink_accepted) + total(%innxmit_accepted) |
+ bytes(total(%innfeed_accepted_size) +
+ total(%innfeed_rejected_size) +
+ total(%innxmit_bytes) +
+ total(%innxmit_accepted_size) +
+ total(%innxmit_rejected_size))";
+ };
+ graph {
+ title "Incoming feeds";
+ value val1;
+ color "#FFFFCE";
+ unit "art";
+ data {
+ name "Offered";
+ color "#50A0D0";
+ value "val2"; # Incoming feeds: Offered
+ };
+ data {
+ name "Accepted";
+ color "#0000FF";
+ value "val3"; # Incoming feeds: Accepted
+ };
+ };
+ graph {
+ title "Outgoing feeds";
+ value val1;
+ color "#FFFFCE";
+ unit "art";
+ data {
+ name "Offered";
+ color "#50A0D0";
+ value "val5"; # Outgoing feeds: Offered
+ };
+ data {
+ name "Accepted";
+ color "#0000FF";
+ value "val6"; # Outgoing feeds: Accepted
+ };
+ };
+ graph {
+ title "Bandwidth";
+ value val1;
+ color "#FFFFCE";
+ unit "Kb";
+ data {
+ name "Incoming";
+ color "#50A0D0";
+ value "byte(val4)"; # Incoming feeds: Volume
+ };
+ data {
+ name "Outgoing";
+ color "#0000FF";
+ value "byte(val7)"; # Outgoing feeds: Volume
+ };
+ };
+};
+
+###########################################################################
+# Report
+
+section prog_type {
+ # skip true; # used to skip a section.
+ title "Log entries by program:";
+ data "%prog_type";
+ sort "$prog_type{$b} <=> $prog_type{$a}";
+ # text false; # to skip this section in the text report
+ # html false; # to skip this section in the HTML report
+ column {
+ name "Program name";
+ format "%-46.46s";
+ value "$key";
+ format_total "TOTAL: %-39.39s";
+ total "$num";
+ };
+ column {
+ name "Lines";
+ format_name "%7s";
+ format "%7d";
+ # text false; # to skip this column in the text report
+ value "$prog_type{$key}";
+ total "total(%prog_type)";
+ };
+ column {
+ name "%Lines";
+ format_name "%7s";
+ format "%6.1f%%";
+ # html false; # to skip this column in the HTML report
+ value "$prog_type{$key} / total(%prog_type) * 100";
+ total "100";
+ };
+ column {
+ name "Size";
+ format "%9s";
+ value "bytes($prog_size{$key})";
+ total "bytes(total(%prog_size))";
+ };
+ column {
+ name "%Size";
+ format_name "%6s";
+ format "%5.1f%%";
+ value "$prog_size{$key} / total(%prog_size) * 100";
+ total "100";
+ };
+};
+
+# INN 2.*
+section innd_his {
+ title "History cache:";
+ data "%innd_his";
+ sort "$innd_his{$b} <=> $innd_his{$a}";
+ column {
+ name "Reason";
+ format "%-57.57s";
+ value "$key";
+ format_total "TOTAL: %-50.50s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%10s";
+ format "%10d";
+ value "$innd_his{$key}";
+ total "total(%innd_his)";
+ };
+ column {
+ name "%Count";
+ format_name "%10s";
+ format "%9.1f%%";
+ value "100 * $innd_his{$key} / total(%innd_his)";
+ total "100";
+ };
+};
+
+# INN 1.*
+section innd_cache {
+ title "History cache:";
+ data "%innd_cache";
+ sort "$innd_cache{$b} <=> $innd_cache{$a}";
+ column {
+ name "Reason";
+ format "%-57.57s";
+ value "$key";
+ format_total "TOTAL: %-50.50s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%10s";
+ format "%10d";
+ value "$innd_cache{$key}";
+ total "total(%innd_cache)";
+ };
+ column {
+ name "%Count";
+ format_name "%10s";
+ format "%9.1f%%";
+ value "100 * $innd_cache{$key} / total(%innd_cache)";
+ total "100";
+ };
+};
+
+section innd_timer {
+ title "INND timer:";
+ data "%innd_time_time";
+ column {
+ name "Code region";
+ format "%-15.15s";
+ value "$key";
+ format_total "TOTAL: %-8.8s";
+ total "time_ms($innd_time_times)";
+ };
+ column {
+ name "Time";
+ format "%13s";
+ value "time_ms($innd_time_time{$key})";
+ total "time_ms(total(%innd_time_time))";
+ };
+ column {
+ name "Pct";
+ format_name "%6s";
+ format "%5.1f%%";
+ value "100 * $innd_time_time{$key} / $innd_time_times";
+ total "100 * total(%innd_time_time) /
+ $innd_time_times";
+ };
+ column {
+ name "Invoked";
+ format "%10s";
+ value "$innd_time_num{$key}";
+ format_total "%9s-";
+ total "";
+ };
+ column {
+ name "Min(ms)";
+ format_name "%9s";
+ format "%9.3f";
+ value "$innd_time_min{$key}";
+ format_total "%8s-";
+ total "";
+ };
+ column {
+ name "Avg(ms)";
+ format_name "%10s";
+ format "%10.3f";
+ value "$innd_time_time{$key} /
+ ($innd_time_num{$key} ? $innd_time_num{$key} : 1)";
+ format_total "%9s-";
+ total "";
+ };
+ column {
+ name "Max(ms)";
+ format_name "%10s";
+ format "%10.3f";
+ value "$innd_time_max{$key}";
+ format_total "%9s-";
+ total "";
+ };
+};
+
+section innfeed_timer {
+ title "INNfeed timer:";
+ data "%innfeed_time_time";
+ column {
+ name "Code region";
+ format "%-15.15s";
+ value "$key";
+ format_total "TOTAL: %-8.8s";
+ total "time_ms($innfeed_time_times)";
+ };
+ column {
+ name "Time";
+ format "%13s";
+ value "time_ms($innfeed_time_time{$key})";
+ total "time_ms(total(%innfeed_time_time))";
+ };
+ column {
+ name "Pct";
+ format_name "%6s";
+ format "%5.1f%%";
+ value "100 * $innfeed_time_time{$key} / $innfeed_time_times";
+ total "100 * total(%innfeed_time_time) /
+ $innfeed_time_times";
+ };
+ column {
+ name "Invoked";
+ format "%10s";
+ value "$innfeed_time_num{$key}";
+ format_total "%9s-";
+ total "";
+ };
+ column {
+ name "Min(ms)";
+ format_name "%9s";
+ format "%9.3f";
+ value "$innfeed_time_min{$key}";
+ format_total "%8s-";
+ total "";
+ };
+ column {
+ name "Avg(ms)";
+ format_name "%10s";
+ format "%10.3f";
+ value "$innfeed_time_time{$key} /
+ ($innfeed_time_num{$key} ? $innfeed_time_num{$key} : 1)";
+ format_total "%9s-";
+ total "";
+ };
+ column {
+ name "Max(ms)";
+ format_name "%10s";
+ format "%10.3f";
+ value "$innfeed_time_max{$key}";
+ format_total "%9s-";
+ total "";
+ };
+};
+
+section nnrpd_timer {
+ title "nnrpd timer:";
+ data "%nnrpd_time_time";
+ column {
+ name "Code region";
+ format "%-15.15s";
+ value "$key";
+ format_total "TOTAL: %-8.8s";
+ total "time_ms($nnrpd_time_times)";
+ };
+ column {
+ name "Time";
+ format "%13s";
+ value "time_ms($nnrpd_time_time{$key})";
+ total "time_ms(total(%nnrpd_time_time))";
+ };
+ column {
+ name "Pct";
+ format_name "%6s";
+ format "%5.1f%%";
+ value "100 * $nnrpd_time_time{$key} / $nnrpd_time_times";
+ total "100 * total(%nnrpd_time_time) /
+ $nnrpd_time_times";
+ };
+ column {
+ name "Invoked";
+ format "%10s";
+ value "$nnrpd_time_num{$key}";
+ format_total "%9s-";
+ total "";
+ };
+ column {
+ name "Min(ms)";
+ format_name "%9s";
+ format "%9.3f";
+ value "$nnrpd_time_min{$key}";
+ format_total "%8s-";
+ total "";
+ };
+ column {
+ name "Avg(ms)";
+ format_name "%10s";
+ format "%10.3f";
+ value "$nnrpd_time_time{$key} /
+ ($nnrpd_time_num{$key} ? $nnrpd_time_num{$key} : 1)";
+ format_total "%9s-";
+ total "";
+ };
+ column {
+ name "Max(ms)";
+ format_name "%10s";
+ format "%10.3f";
+ value "$nnrpd_time_max{$key}";
+ format_total "%9s-";
+ total "";
+ };
+};
+
+section innd_control {
+ title "Control commands to INND:";
+ data "%innd_control";
+ column {
+ name "Command";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Number";
+ format_name "%7s";
+ value "$innd_control{$key}";
+ format "%7d";
+ total "total(%innd_control)";
+ };
+};
+
+section innd_newgroup {
+ title "Newsgroups created:";
+ data "%innd_newgroup";
+ column {
+ name "Group";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL%-66.66s";
+ total "";
+ };
+ column {
+ name "Mode";
+ value "$innd_newgroup{$key}";
+ format "%7s";
+ total "$num";
+ };
+};
+
+section innd_changegroup {
+ title "Newsgroups changed:";
+ data "%innd_changegroup";
+ column {
+ name "Group";
+ format "%-68.68s";
+ value "$key";
+ format_total "TOTAL%-63.63s";
+ total "";
+ };
+ column {
+ name "New mode";
+ format "%10s";
+ value "$innd_changegroup{$key}";
+ total "$num";
+ };
+};
+
+section innd_rmgroup {
+ title "Newsgroups removed:";
+ data "%innd_rmgroup";
+ column {
+ name "Group";
+ format "%-78.78s";
+ value "$key";
+ format_total "TOTAL: %-71.71s";
+ total "$num";
+ };
+};
+
+section controlchan {
+ title "Control Channel:";
+ data "%controlchan_who";
+ column {
+ name "Sender";
+ format "%-25.25s";
+ value "$key";
+ format_total "TOTAL%-20.20s";
+ total "";
+ };
+ column {
+ name "newgroup";
+ value "$controlchan_new{$key}";
+ format "%8s";
+ total "total(%controlchan_new)";
+ };
+ column {
+ name "rmgroup";
+ value "$controlchan_rm{$key}";
+ format "%8s";
+ total "total(%controlchan_rm)";
+ };
+ column {
+ name "Other";
+ value "$controlchan_other{$key}";
+ format "%8s";
+ total "total(%controlchan_other)";
+ };
+ column {
+ name "Bad PGP";
+ value "$controlchan_skippgp{$key}";
+ format "%8s";
+ total "total(%controlchan_skippgp)";
+ };
+ column {
+ name "DoIt";
+ value "$controlchan_doit{$key}";
+ format "%8s";
+ total "total(%controlchan_doit)";
+ };
+ column {
+ name "OK";
+ value "$controlchan_ok{$key}";
+ format "%8s";
+ total "total(%controlchan_ok)";
+ };
+};
+
+section innd_connect {
+ title "Incoming Feeds (INN):";
+ data "%innd_seconds";
+ sort "$innd_accepted{$b} <=> $innd_accepted{$a}";
+ numbering true;
+ column {
+ name "Server";
+ format_name "%-21.21s";
+ format "%-24.24s";
+ value "$key";
+ format_total "TOTAL: %-17.17s";
+ total "$num";
+ };
+ column {
+ name "Connects";
+ format_name "%5s";
+ format "%5d";
+ value "$innd_connect{$key}";
+ total "total(%innd_connect)";
+ };
+ column {
+ name "Offered";
+ format_name "%8s";
+ format "%8d";
+ value "$innd_offered{$key}";
+ total "total(%innd_offered)";
+ };
+ column {
+ name "Taken";
+ format_name "%7s";
+ format "%7d";
+ value "$innd_accepted{$key}";
+ total "total(%innd_accepted)";
+ };
+ column {
+ name "Refused";
+ format_name "%7s";
+ format "%7d";
+ value "$innd_refused{$key}";
+ total "total(%innd_refused)";
+ };
+ column {
+ name "Reject";
+ format_name "%7s";
+ format "%7d";
+ value "$innd_rejected{$key}";
+ total "total(%innd_rejected)";
+ };
+ column {
+ name "%Accpt";
+ format_name "%6s";
+ format "%4d%%";
+ value "$innd_offered{$key} == 0 ? 0 :
+ $innd_accepted{$key} / $innd_offered{$key} * 100";
+ total "total(%innd_offered) == 0 ? 0 :
+ total(%innd_accepted) / total(%innd_offered) * 100";
+ };
+ column {
+ name "Elapsed";
+ format_name "%8s";
+ format "%9s";
+ value "time($innd_seconds{$key})";
+ total "time(total(%innd_seconds))";
+ };
+ graph {
+ title "Articles received by server";
+ type histo3d;
+ sort "%innd_accepted";
+ data {
+ name "Articles accepted";
+ color "#0000FF";
+ value "%innd_accepted";
+ };
+ data {
+ name "Articles refused";
+ color "#FFAF00";
+ value "%innd_refused";
+ };
+ data {
+ name "Articles rejected";
+ color "#FF0000";
+ value "%innd_rejected";
+ };
+ };
+};
+
+section innd_incoming_vol {
+ title "Incoming Volume (INN):";
+ data "%innd_seconds";
+ sort "$innd_stored_size{$b} <=> $innd_stored_size{$a}";
+ numbering true;
+ column {
+ name "Server";
+ format "%-24.24s";
+ value "$key";
+ format_total "TOTAL: %-17.17s";
+ total "$num";
+ };
+ column {
+ name "AcceptVol";
+ format "%9s";
+ value "bytes($innd_stored_size{$key})";
+ total "bytes(total(%innd_stored_size))";
+ };
+ column {
+ name "DupVol";
+ format "%9s";
+ value "bytes($innd_duplicated_size{$key})";
+ total "bytes(total(%innd_duplicated_size))";
+ };
+ column {
+ name "TotalVol";
+ format "%9s";
+ value "bytes($innd_stored_size{$key} +
+ $innd_duplicated_size{$key})";
+ total "bytes(total(%innd_stored_size) +
+ total(%innd_duplicated_size))";
+ };
+ column {
+ name "%Acc";
+ format_name "%4s";
+ format "%3d%%";
+ value "$innd_offered_size{$key} == 0 ? 0 :
+ $innd_stored_size{$key} / $innd_offered_size{$key} * 100";
+ total "total(%innd_offered_size) == 0 ? 0 :
+ total(%innd_stored_size) / total(%innd_offered_size) * 100";
+ };
+ column {
+ name "Vol/Art";
+ format "%9s";
+ value "bytes(($innd_stored_size{$key} +
+ $innd_duplicated_size{$key}) /
+ ($innd_accepted{$key} +
+ $innd_rejected{$key}))";
+ total "bytes((total(%innd_stored_size) +
+ total(%innd_duplicated_size)) /
+ (total(%innd_accepted) +
+ total(%innd_rejected)))";
+ };
+ column {
+ name "Elapsed";
+ format "%9s";
+ value "time($innd_seconds{$key})";
+ total "time(total(%innd_seconds))";
+ };
+ graph {
+ title "Incoming Volume received by server";
+ type histo3d;
+ sort "%innd_stored_size";
+ data {
+ name "Accepted Volume";
+ color "#0000FF";
+ value "%innd_stored_size";
+ };
+ data {
+ name "Duplicated Volume";
+ color "#FFAF00";
+ value "%innd_duplicated_size";
+ };
+ };
+};
+
+section inn_flow {
+ title "Incoming articles:";
+ data "%inn_flow";
+ sort "&DateCompare";
+ column {
+ name "Date";
+ format "%-27.27s";
+ value "$key";
+ format_total "TOTAL: %-20.20s";
+ total "time(total(%inn_flow_time))";
+ };
+ column {
+ name "Articles";
+ format_name "%8s";
+ value "$inn_flow{$key}";
+ format "%8d";
+ total "total(%inn_flow)";
+ };
+ column {
+ name "%Arts";
+ format_name "%8s";
+ value "$inn_flow{$key} / $inn_flow_total * 100";
+ format "%7.1f%%";
+ total "100";
+ };
+ column {
+ name "Art/sec";
+ format_name "%7s";
+ value "$inn_flow{$key} / $inn_flow_time{$key}";
+ format "%7.2f";
+ total "total(%inn_flow) / total(%inn_flow_time)";
+ };
+ column {
+ name "Size";
+ value "bytes($inn_flow_size{$key})";
+ format "%9s";
+ total "bytes(total(%inn_flow_size))";
+ };
+ column {
+ name "%Size";
+ format_name "%7s";
+ value "$inn_flow_size{$key} /
+ total(%inn_flow_size) * 100";
+ format "%6.1f%%";
+ total "100";
+ };
+ column {
+ name "KB/sec";
+ format_name "%7s";
+ value "$inn_flow_size{$key} /
+ $inn_flow_time{$key} / 1024";
+ format "%7.2f";
+ total "total(%inn_flow_size) /
+ total(%inn_flow_time) / 1024";
+ };
+ graph {
+ title "Incoming articles";
+ type histo;
+ data {
+ name "Hours";
+ value "%inn_flow_labels";
+ };
+ data {
+ name "Art/sec";
+ factor 3600;
+ value "%inn_flow";
+ };
+ };
+ graph {
+ title "Incoming articles (size)";
+ type histo;
+ data {
+ name "Hours";
+ value "%inn_flow_labels";
+ };
+ data {
+ name "Kb/sec";
+ factor 3686400; # 3600 * 1024
+ value "%inn_flow_size";
+ };
+ };
+};
+
+section cnfsstat {
+ title "CNFS buffer status:";
+ data "%cnfsstat";
+ column {
+ name "Buffer";
+ format "%-13.13s";
+ value "$key";
+ format_total "TOTAL: %-6.6s";
+ total "$num";
+ };
+ column {
+ name "Class";
+ format "%-13.13s";
+ value "$cnfsstat{$key}";
+ format_total "-%12s";
+ total "";
+ };
+ column {
+ name "Size";
+ format "%9s";
+ value "bytes($cnfsstat_size{$key})";
+ total "bytes(total(%cnfsstat_size))";
+ };
+ column {
+ name "Used";
+ format "%9s";
+ value "bytes($cnfsstat_used{$key})";
+ total "bytes(total(%cnfsstat_used))";
+ };
+ column {
+ name "%Used";
+ format_name "%7s";
+ value "$cnfsstat_used{$key} /
+ $cnfsstat_size{$key} * 100";
+ format "%6.1f%%";
+ total "total(%cnfsstat_used) /
+ total(%cnfsstat_size) * 100";
+ };
+ column {
+ name "Cycles";
+ format_name "%6s";
+ format "%6d";
+ value "$cnfsstat_cycles{$key}";
+ total "total(%cnfsstat_cycles)";
+ };
+ column {
+ name "KB/sec";
+ format_name "%7s";
+ value "$cnfsstat_rate{$key} /
+ $cnfsstat_samples{$key} / 1024";
+ format "%7.2f";
+ total "total(%cnfsstat_rate) /
+ total(%cnfsstat_samples) / 1024";
+ };
+ column {
+ name "Days";
+ format_name "%8s";
+ value "$cnfsstat_size{$key} /
+ ($cnfsstat_rate{$key} /
+ $cnfsstat_samples{$key}) / 86400";
+ format "%8.2f";
+ format_total "%7s-";
+ total "";
+ };
+};
+
+section inn_unwanted {
+ title "Sites sending bad articles:";
+ data "%inn_badart";
+ sort "$inn_badart{$b} <=> $inn_badart{$a}";
+ numbering true;
+ column {
+ name "Server";
+ format "%-23.23s";
+ value "$key";
+ format_total "TOTAL: %-16.16s";
+ total "$num";
+ };
+ column {
+ name "Total";
+ format_name "%6s";
+ format "%6d";
+ value "$inn_badart{$key}";
+ total "total(%inn_badart)";
+ };
+ column {
+ name "Group";
+ format_name "%6s";
+ format "%6d";
+ value "$inn_uw_ng_s{$key}";
+ total "total(%inn_uw_ng_s)";
+ };
+ column {
+ name "Dist";
+ format_name "%5s";
+ format "%5d";
+ value "$inn_uw_dist_s{$key}";
+ total "total(%inn_uw_dist_s)";
+ };
+ column {
+ name "Duplic";
+ format_name "%6s";
+ format "%6d";
+ value "$inn_duplicate{$key}";
+ total "total(%inn_duplicate)";
+ };
+ column {
+ name "Unapp";
+ format_name "%5s";
+ format "%5d";
+ value "$inn_unapproved{$key}";
+ total "total(%inn_unapproved)";
+ };
+ column {
+ name "TooOld";
+ format_name "%6s";
+ format "%6d";
+ value "$inn_tooold{$key}";
+ total "total(%inn_tooold)";
+ };
+ column {
+ name "Site";
+ format_name "%4s";
+ format "%4d";
+ value "$inn_uw_site{$key}";
+ total "total(%inn_uw_site)";
+ };
+ column {
+ name "Line";
+ format_name "%4s";
+ format "%4d";
+ value "$inn_linecount{$key}";
+ total "total(%inn_linecount)";
+ };
+ column {
+ name "Other";
+ format_name "%5s";
+ format "%5d";
+ value "$innd_others{$key}";
+ total "total(%innd_others)";
+ };
+};
+
+section inn_unwanted_group {
+ title "Unwanted newsgroups:";
+ top 20; # default 'top' value or use 'top_text' and 'top_html'
+ # to specify different values for text and HTML reports.
+ data "%inn_uw_ng";
+ sort "$inn_uw_ng{$b} <=> $inn_uw_ng{$a}";
+ column {
+ name "Newsgroup";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%7s";
+ format "%7d";
+ value "$inn_uw_ng{$key}";
+ total "total(%inn_uw_ng)";
+ };
+};
+
+section inn_unwanted_dist {
+ title "Unwanted distributions:";
+ top 20;
+ data "%inn_uw_dist";
+ sort "$inn_uw_dist{$b} <=> $inn_uw_dist{$a}";
+ column {
+ name "Distribution";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%7s";
+ format "%7d";
+ value "$inn_uw_dist{$key}";
+ total "total(%inn_uw_dist)";
+ };
+};
+
+section inn_unwanted_unapp {
+ title "Supposedly-moderated groups with unmoderated postings:";
+ top 20;
+ data "%inn_unapproved_g";
+ sort "$inn_unapproved_g{$b} <=> $inn_unapproved_g{$a}";
+ column {
+ name "Groups";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%7s";
+ format "%7d";
+ value "$inn_unapproved_g{$key}";
+ total "total(%inn_unapproved_g)";
+ };
+};
+
+section inn_unwanted_path {
+ title "Unwanted sites in Path:";
+ top 20;
+ data "%inn_site_path";
+ sort "$inn_site_path{$b} <=> $inn_site_path{$a}";
+ column {
+ name "Site";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%7s";
+ format "%7d";
+ value "$inn_site_path{$key}";
+ total "total(%inn_site_path)";
+ };
+};
+
+section innd_perl {
+ title "INND Perl filter:";
+ top 20;
+ data "%innd_filter_perl";
+ sort "$innd_filter_perl{$b} <=> $innd_filter_perl{$a}";
+ column {
+ name "Reason";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%7s";
+ format "%7d";
+ value "$innd_filter_perl{$key}";
+ total "total(%innd_filter_perl)";
+ };
+};
+
+section innd_python {
+ title "INND Python filter:";
+ top 20;
+ data "%innd_filter_python";
+ sort "$innd_filter_python{$b} <=> $innd_filter_python{$a}";
+ column {
+ name "Reason";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%7s";
+ format "%7d";
+ value "$innd_filter_python{$key}";
+ total "total(%innd_filter_python)";
+ };
+};
+
+section nocem {
+ title "NoCeM on Spool:";
+ data "%nocem_goodsigs";
+ sort "$nocem_goodsigs{$b} <=> $nocem_goodsigs{$a}";
+ column {
+ name "Id";
+ format "%-47.47s";
+ value "$key";
+ format_total "TOTAL: %-40.40s";
+ total "$num";
+ };
+ column {
+ name "Good";
+ format "%7s";
+ value "$nocem_goodsigs{$key}";
+ total "total(%nocem_goodsigs)";
+ };
+ column {
+ name "Bad";
+ format "%7s";
+ value "$nocem_badsigs{$key}";
+ total "total(%nocem_badsigs)";
+ };
+ column {
+ name "Unique";
+ format "%7s";
+ value "$nocem_newids{$key}";
+ total "total(%nocem_newids)";
+ };
+ column {
+ name "Total";
+ format "%7s";
+ value "$nocem_totalids{$key}";
+ total "total(%nocem_totalids)";
+ };
+};
+
+section innd_no_permission {
+ title "INND no permission servers:";
+ data "%innd_no_permission";
+ sort "$innd_no_permission{$b} <=> $innd_no_permission{$a}";
+ column {
+ name "System";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%7s";
+ format "%7d";
+ value "$innd_no_permission{$key}";
+ total "total(%innd_no_permission)";
+ };
+};
+
+section innd_max_conn {
+ title "Too many incoming connections (innd):";
+ data "%innd_max_conn";
+ sort "$innd_max_conn{$b} <=> $innd_max_conn{$a}";
+ column {
+ name "Server";
+ format "%-70.70s";
+ value "$key";
+ format_total "TOTAL: %-63.63s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%8s";
+ format "%8d";
+ value "$innd_max_conn{$key}";
+ total "total(%innd_max_conn)";
+ };
+};
+
+section innd_too_many_connects_per_minute {
+ title "INND too many connects per minute:";
+ data "%innd_too_many_connects_per_minute";
+ sort "$innd_too_many_connects_per_minute{$b} <=>
+ $innd_too_many_connects_per_minute{$a}";
+ column {
+ name "System";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%7s";
+ format "%7d";
+ value "$innd_too_many_connects_per_minute{$key}";
+ total "total(%innd_too_many_connects_per_minute)";
+ };
+};
+
+section innd_misc {
+ title "INND misc events:";
+ data "%innd_misc";
+ sort "$innd_misc{$b} <=> $innd_misc{$a}";
+ column {
+ name "Events";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%7s";
+ format "%7d";
+ value "$innd_misc{$key}";
+ total "total(%innd_misc)";
+ };
+};
+
+section innd_misc_stat {
+ title "Miscellaneous innd statistics:";
+ data "%innd_misc_stat";
+ sort "$innd_misc_stat{$b} <=> $innd_misc_stat{$a}";
+ double true;
+ top 10;
+ #numbering true;
+ column {
+ primary true;
+ name "Event";
+ format "%-69.69s";
+ value "$key1";
+ format_total "TOTAL: %-62.62s";
+ total "$num";
+ };
+ column {
+ name "Server";
+ format " %-67.67s";
+ value "$key2";
+ total "$num";
+ format_total "TOTAL: %-60.60s";
+ };
+ column {
+ name "Number";
+ format_name "%9s";
+ format "%9d";
+ value "$innd_misc_stat{$key1}{$key2}";
+ total "total(%innd_misc_stat)";
+ };
+};
+
+section innfeed_connect {
+ title "Outgoing Feeds (innfeed) by Articles:";
+ data "%innfeed_offered";
+ sort "$innfeed_accepted{$b} <=> $innfeed_accepted{$a}";
+ numbering true;
+ column {
+ name "Server";
+ format "%-18.18s";
+ value "$key";
+ format_total "TOTAL: %-11.11s";
+ total "$num";
+ };
+ column {
+ name "Offered";
+ format_name "%7s";
+ format "%7d";
+ value "$innfeed_offered{$key}";
+ total "total(%innfeed_offered)";
+ };
+ column {
+ name "Taken";
+ format_name "%7s";
+ format "%7d";
+ value "$innfeed_accepted{$key}";
+ total "total(%innfeed_accepted)";
+ };
+ column {
+ name "Refused";
+ format_name "%7s";
+ format "%7d";
+ value "$innfeed_refused{$key}";
+ total "total(%innfeed_refused)";
+ };
+ column {
+ name "Reject";
+ format_name "%6s";
+ format "%6d";
+ value "$innfeed_rejected{$key}";
+ total "total(%innfeed_rejected)";
+ };
+ column {
+ name "Miss";
+ format_name "%6s";
+ format "%6d";
+ value "$innfeed_missing{$key}";
+ total "total(%innfeed_missing)";
+ };
+ column {
+ name "Spool";
+ format_name "%7s";
+ format "%7d";
+ value "$innfeed_spooled{$key}";
+ total "total(%innfeed_spooled)";
+ };
+ column {
+ name "%Took";
+ format_name "%5s";
+ format "%3d%%";
+ value "$innfeed_offered{$key} == 0 ? 0 :
+ $innfeed_accepted{$key} / $innfeed_offered{$key} * 100";
+ total "total(%innfeed_offered) == 0 ? 0 :
+ total(%innfeed_accepted) / total(%innfeed_offered) * 100";
+ };
+ column {
+ name "Elapsed";
+ format_name "%8s";
+ format "%9s";
+ value "time($innfeed_seconds{$key})";
+ total "time(total(%innfeed_seconds))";
+ };
+ graph {
+ title "Outgoing feeds (innfeed) by Articles";
+ type histo3d;
+ sort "%innfeed_accepted";
+ data {
+ name "Accepted";
+ color "#0000FF";
+ value "%innfeed_accepted";
+ };
+ data {
+ name "Refused";
+ color "#FFAF00";
+ value "%innfeed_refused";
+ };
+ data {
+ name "Rejected";
+ color "#FF0000";
+ value "%innfeed_rejected";
+ };
+ data {
+ name "Missing";
+ color "#00FF00";
+ value "%innfeed_missing";
+ };
+ data {
+ name "Spooled";
+ color "#AF00FF";
+ value "%innfeed_spooled,";
+ };
+ };
+};
+
+section innfeed_volume {
+ title "Outgoing Feeds (innfeed) by Volume:";
+ data "%innfeed_offered";
+ sort "$innfeed_accepted_size{$b} <=> $innfeed_accepted_size{$a}";
+ numbering true;
+ column {
+ name "Server";
+ format "%-17.17s";
+ value "$key";
+ format_total "TOTAL: %-10.10s";
+ total "$num";
+ };
+ column {
+ name "AcceptVol";
+ format "%9s";
+ value "bytes($innfeed_accepted_size{$key})";
+ total "bytes(total(%innfeed_accepted_size))";
+ };
+ column {
+ name "RejectVol";
+ format "%9s";
+ value "bytes($innfeed_rejected_size{$key})";
+ total "bytes(total(%innfeed_rejected_size))";
+ };
+ column {
+ name "TotalVol";
+ format "%9s";
+ value "bytes($innfeed_accepted_size{$key} +
+ $innfeed_rejected_size{$key})";
+ total "bytes(total(%innfeed_accepted_size) +
+ total(%innfeed_rejected_size))";
+ };
+ column {
+ name "Volume/sec";
+ format_name "%11s";
+ format "%9s/s";
+ value "bytes(($innfeed_accepted_size{$key} +
+ $innfeed_rejected_size{$key}) /
+ $innfeed_seconds{$key})";
+ total "bytes((total(%innfeed_accepted_size) +
+ total(%innfeed_rejected_size)) /
+ total(%innfeed_seconds))";
+ };
+ column {
+ name "Vol/Art";
+ format "%9s";
+ value "bytes(($innfeed_accepted_size{$key} +
+ $innfeed_rejected_size{$key}) /
+ ($innfeed_accepted{$key} +
+ $innfeed_rejected{$key}))";
+ total "bytes((total(%innfeed_accepted_size) +
+ total(%innfeed_rejected_size)) /
+ (total(%innfeed_accepted) +
+ total(%innfeed_rejected)))";
+ };
+ column {
+ name "Elapsed";
+ format "%9s";
+ value "time($innfeed_seconds{$key})";
+ total "time(total(%innfeed_seconds))";
+ };
+ graph {
+ title "Outgoing feeds (innfeed) by Volume";
+ type histo3d;
+ sort "%innfeed_accepted_size";
+ data {
+ name "Accepted";
+ color "#0000FF";
+ value "%innfeed_accepted_size";
+ };
+ data {
+ name "Rejected";
+ color "#FFAF00";
+ value "%innfeed_rejected_size";
+ };
+ data {
+ name "Total";
+ color "#00FF00";
+ value "%innfeed_accepted_size +
+ %innfeed_rejected_size";
+ };
+ };
+};
+
+section innfeed_shrunk {
+ title "Backlog files shrunk by innfeed:";
+ data "%innfeed_shrunk";
+ sort "$innfeed_shrunk{$b} <=> $innfeed_shrunk{$a}";
+ column {
+ name "Server";
+ format "%-70.70s";
+ value "$key";
+ format_total "TOTAL: %-63.63s";
+ total "$num";
+ };
+ column {
+ name "Size";
+ format "%8s";
+ value "bytes($innfeed_shrunk{$key})";
+ total "bytes(total(%innfeed_shrunk))";
+ };
+};
+
+section nntplink_connect {
+ title "Outgoing Feeds (nntplink):";
+ data "%nntplink_site";
+ sort "$nntplink_accepted{$b} <=> $nntplink_accepted{$a}";
+ numbering true;
+ column {
+ name "Server";
+ format "%-25.25s";
+ value "$key";
+ format_total "TOTAL: %-18.18s";
+ total "$num";
+ };
+ column {
+ name "Offered";
+ format_name "%8s";
+ format "%8d";
+ value "$nntplink_offered{$key}";
+ total "total(%nntplink_offered)";
+ };
+ column {
+ name "Taken";
+ format_name "%8s";
+ format "%8d";
+ value "$nntplink_accepted{$key}";
+ total "total(%nntplink_accepted)";
+ };
+ column {
+ name "Rejected";
+ format_name "%8s";
+ format "%8d";
+ value "$nntplink_rejected{$key}";
+ total "total(%nntplink_rejected)";
+ };
+ column {
+ name "Failed";
+ format_name "%8s";
+ format "%8d";
+ value "$nntplink_failed{$key}";
+ total "total(%nntplink_failed)";
+ };
+ column {
+ name "%Accpt";
+ format_name "%6s";
+ format "%5d%%";
+ value "$nntplink_offered{$key} == 0 ? 0 :
+ $nntplink_accepted{$key} / $nntplink_offered{$key} * 100";
+ total "total(%nntplink_offered) == 0 ? 0 :
+ total(%nntplink_accepted) / total(%nntplink_offered) * 100";
+ };
+ column {
+ name "Elapsed";
+ format "%10s";
+ value "time($nntplink_times{$key})";
+ total "time(total(%nntplink_times))";
+ };
+ graph {
+ title "Outgoing Feeds (nntplink)";
+ type histo3d;
+ sort "%nntplink_accepted";
+ data {
+ name "Articles accepted";
+ color "#0000FF";
+ value "%nntplink_accepted";
+ };
+ data {
+ name "Articles rejected";
+ color "#FFAF00";
+ value "%nntplink_rejected";
+ };
+ data {
+ name "Articles failed";
+ color "#FF0000";
+ value "%nntplink_failed";
+ };
+ };
+};
+
+section nntplink_connect2 {
+ title "Outgoing Feeds (nntplink) - other information:";
+ data "%nntplink_site";
+ sort "$nntplink_accepted{$b} <=> $nntplink_accepted{$a}";
+ numbering true;
+ column {
+ name "Server";
+ format "%-20.20s";
+ value "$key";
+ format_total "TOTAL: %-13.13s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%4s";
+ format "%4d";
+ value "$nntplink_site{$key}";
+ total "total(%nntplink_site)";
+ };
+ column {
+ name "Ok";
+ format_name "%4s";
+ format "%4d";
+ value "$nntplink_site{$key} - ($nntplink_eof{$key} +
+ $nntplink_sockerr{$key} +
+ $nntplink_selecterr{$key} +
+ $nntplink_hiload{$key} + $nntplink_bpipe{$key} +
+ $nntplink_nospace{$key} + $nntplink_auth{$key} +
+ $nntplink_expire{$key} + $nntplink_fail{$key})";
+ total "total(%nntplink_site) - (total(%nntplink_eof) +
+ total(%nntplink_sockerr) +
+ total(%nntplink_selecterr) +
+ total(%nntplink_hiload) +
+ total(%nntplink_bpipe) +
+ total(%nntplink_nospace) +
+ total(%nntplink_auth) +
+ total(%nntplink_expire) +
+ total(%nntplink_fail))";
+ };
+ column {
+ name "EOF";
+ format_name "%3s";
+ format "%3d";
+ value "$nntplink_eof{$key}";
+ total "total(%nntplink_eof)";
+ };
+ column {
+ name "Sock";
+ format_name "%4s";
+ format "%4d";
+ value "$nntplink_sockerr{$key}";
+ total "total(%nntplink_sockerr)";
+ };
+ column {
+ name "Slct";
+ format_name "%4s";
+ format "%4d";
+ value "$nntplink_selecterr{$key}";
+ total "total(%nntplink_selecterr)";
+ };
+ column {
+ name "Load";
+ format_name "%4s";
+ format "%4d";
+ value "$nntplink_hiload{$key}";
+ total "total(%nntplink_hiload)";
+ };
+ column {
+ name "Bpip";
+ format_name "%4s";
+ format "%4d";
+ value "$nntplink_bpipe{$key}";
+ total "total(%nntplink_bpipe)";
+ };
+ column {
+ name "Spce";
+ format_name "%4s";
+ format "%4d";
+ value "$nntplink_nospace{$key}";
+ total "total(%nntplink_nospace)";
+ };
+ column {
+ name "Exp";
+ format_name "%4s";
+ format "%4d";
+ value "$nntplink_expire{$key}";
+ total "total(%nntplink_expire)";
+ };
+ column {
+ name "Auth";
+ format_name "%4s";
+ format "%4d";
+ value "$nntplink_auth{$key}";
+ total "total(%nntplink_auth)";
+ };
+ column {
+ name "Othr";
+ format_name "%4s";
+ format "%4d";
+ value "$nntplink_fail{$key}";
+ total "total(%nntplink_fail)";
+ };
+ column {
+ name "Pct";
+ format_name "%4s";
+ format "%3d%%";
+ value "$nntplink_site{$key} ?
+ 100 * ($nntplink_site{$key} -
+ ($nntplink_eof{$key} + $nntplink_sockerr{$key} +
+ $nntplink_selecterr{$key} +
+ $nntplink_hiload{$key} + $nntplink_bpipe{$key} +
+ $nntplink_nospace{$key} + $nntplink_auth{$key} +
+ $nntplink_expire{$key} +
+ $nntplink_fail{$key})) / $nntplink_site{$key} : 0";
+ total "total(%nntplink_site) ?
+ 100 * (total(%nntplink_site) -
+ (total(%nntplink_eof) +
+ total(%nntplink_sockerr) +
+ total(%nntplink_selecterr) +
+ total(%nntplink_hiload) +
+ total(%nntplink_bpipe) +
+ total(%nntplink_nospace) +
+ total(%nntplink_auth) +
+ total(%nntplink_expire) +
+ total(%nntplink_fail))) / total(%nntplink_site) : 0";
+ };
+};
+
+section innxmit_connect {
+ title "Outgoing Feeds (innxmit) by Articles:";
+ data "%innxmit_times";
+ sort "$innxmit_accepted{$b} <=> $innxmit_accepted{$a}";
+ numbering true;
+ column {
+ name "Server";
+ format "%-27.27s";
+ value "$key";
+ format_total "TOTAL: %-20.20s";
+ total "$num";
+ };
+ column {
+ name "Offered";
+ format_name "%7s";
+ format "%7d";
+ value "$innxmit_offered{$key}";
+ total "total(%innxmit_offered)";
+ };
+ column {
+ name "Taken";
+ format_name "%7s";
+ format "%7d";
+ value "$innxmit_accepted{$key}";
+ total "total(%innxmit_accepted)";
+ };
+ column {
+ name "Refused";
+ format_name "%7s";
+ format "%7d";
+ value "$innxmit_refused{$key}";
+ total "total(%innxmit_refused)";
+ };
+ column {
+ name "Reject";
+ format_name "%7s";
+ format "%7d";
+ value "$innxmit_rejected{$key}";
+ total "total(%innxmit_rejected)";
+ };
+ column {
+ name "Miss";
+ format_name "%5s";
+ format "%5d";
+ value "$innxmit_missing{$key}";
+ total "total(%innxmit_rejected)";
+ };
+ column {
+ name "%Acc";
+ format_name "%4s";
+ format "%3d%%";
+ value "$innxmit_offered{$key} == 0 ? 0 :
+ $innxmit_accepted{$key} / $innxmit_offered{$key} * 100";
+ total "total(%innxmit_offered) == 0 ? 0 :
+ total(%innxmit_accepted) / total(%innxmit_offered) * 100";
+ };
+ column {
+ name "Elapsed";
+ format "%8s";
+ value "time($innxmit_times{$key})";
+ total "time(total(%innxmit_times))";
+ };
+ graph {
+ title "Outgoing Feeds (innxmit)";
+ type histo3d;
+ sort "%innxmit_accepted";
+ data {
+ name "Art. accepted";
+ color "#0000FF";
+ value "%innxmit_accepted";
+ };
+ data {
+ name "Art. refused";
+ color "#FFAF00";
+ value "%innxmit_refused";
+ };
+ data {
+ name "Art. rejected";
+ color "#FF0000";
+ value "%innxmit_rejected";
+ };
+ data {
+ name "Art. missing";
+ color "#00FF00";
+ value "%innxmit_missing";
+ };
+ };
+};
+
+section innxmit_volume {
+ title "Outgoing Feeds (innxmit) by Volume:";
+ data "%innxmit_accepted_size";
+ sort "$innxmit_accepted_size{$b} <=> $innxmit_accepted_size{$a}";
+ numbering true;
+ column {
+ name "Server";
+ format "%-24.24s";
+ value "$key";
+ format_total "TOTAL: %-17.17s";
+ total "$num";
+ };
+ column {
+ name "AcceptVol";
+ format "%9s";
+ value "bytes($innxmit_accepted_size{$key})";
+ total "bytes(total(%innxmit_accepted_size))";
+ };
+ column {
+ name "RejectVol";
+ format "%9s";
+ value "bytes($innxmit_rejected_size{$key})";
+ total "bytes(total(%innxmit_rejected_size))";
+ };
+ column {
+ name "TotalVol";
+ format "%9s";
+ value "bytes($innxmit_accepted_size{$key} +
+ $innxmit_rejected_size{$key} +
+ $innxmit_bytes{$key})";
+ total "bytes(total(%innxmit_accepted_size) +
+ total(%innxmit_rejected_size) +
+ total(%innxmit_bytes))";
+ };
+ column {
+ name "KB/s";
+ format_name "%5s";
+ format "%5.1f";
+ value "($innxmit_accepted_size{$key} +
+ $innxmit_rejected_size{$key} +
+ $innxmit_bytes{$key}) /
+ $innxmit_times{$key} / 1024";
+ total "(total(%innxmit_accepted_size) +
+ total(%innxmit_rejected_size) +
+ total(%innxmit_bytes)) /
+ total(%innxmit_times) / 1024";
+ };
+ column {
+ name "Vol/Art";
+ format "%9s";
+ value "bytes(($innxmit_accepted_size{$key} +
+ $innxmit_rejected_size{$key} +
+ $innxmit_bytes{$key}) /
+ ($innxmit_accepted{$key} +
+ $innxmit_rejected{$key}))";
+ total "bytes((total(%innxmit_accepted_size) +
+ total(%innxmit_rejected_size) +
+ total(%innxmit_bytes)) /
+ (total(%innxmit_accepted) +
+ total(%innxmit_rejected)))";
+ };
+ column {
+ name "Elapsed";
+ format "%8s";
+ value "time($innxmit_times{$key})";
+ total "time(total(%innxmit_times))";
+ };
+ graph {
+ title "Outgoing Feeds (innxmit)";
+ type histo3d;
+ sort "%innxmit_accepted";
+ data {
+ name "Articles accepted";
+ color "#0000FF";
+ value "%innxmit_accepted_size";
+ };
+ data {
+ name "Articles rejected";
+ color "#FFAF00";
+ value "%innxmit_rejected_size";
+ };
+ data {
+ name "Total";
+ color "#FF0000";
+ value "%innxmit_missing";
+ };
+ };
+};
+
+
+section innxmit_connect2 {
+ title "Outgoing Feeds (innxmit) - other information:";
+ data "%innxmit_site";
+ sort "$innxmit_accepted{$b} <=> $innxmit_accepted{$a}";
+ numbering true;
+ column {
+ name "Server";
+ format "%-25.25s";
+ value "$key";
+ format_total "TOTAL: %-18.18s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%5s";
+ format "%5d";
+ value "$innxmit_site{$key}";
+ total "total(%innxmit_site)";
+ };
+ column {
+ name "Ok";
+ format_name "%5s";
+ format "%5d";
+ value "$innxmit_site{$key} -
+ ($innxmit_afail_host{$key} +
+ $innxmit_hiload{$key} + $innxmit_nospace{$key} +
+ $innxmit_cfail_host{$key} +
+ $innxmit_expire{$key} + $innxmit_crefused{$key})";
+ total "total(%innxmit_site) -
+ (total(%innxmit_afail_host) +
+ total(%innxmit_hiload) +
+ total(%innxmit_nospace) +
+ total(%innxmit_cfail_host) +
+ total(%innxmit_expire) +
+ total(%innxmit_crefused))";
+ };
+ column {
+ name "Auth";
+ format_name "%4s";
+ format "%4d";
+ value "$innxmit_afail_host{$key}";
+ total "total(%innxmit_afail_host)";
+ };
+ column {
+ name "Load";
+ format_name "%4s";
+ format "%4d";
+ value "$innxmit_hiload{$key}";
+ total "total(%innxmit_hiload)";
+ };
+ column {
+ name "Space";
+ format_name "%5s";
+ format "%5d";
+ value "$innxmit_nospace{$key}";
+ total "total(%innxmit_nospace)";
+ };
+ column {
+ name "Expire";
+ format_name "%6s";
+ format "%6d";
+ value "$innxmit_expire{$key}";
+ total "total(%innxmit_expire)";
+ };
+ column {
+ name "Connct";
+ format_name "%6s";
+ format "%6d";
+ value "$innxmit_cfail_host{$key}";
+ total "total(%innxmit_cfail_host)";
+ };
+ column {
+ name "Other";
+ format_name "%6s";
+ format "%6d";
+ value "$innxmit_crefused{$key}";
+ total "total(%innxmit_crefused)";
+ };
+ column {
+ name "Pct";
+ format_name "%4s";
+ format "%3d%%";
+ value "$innxmit_site{$key} ? 100 *
+ ($innxmit_site{$key} -
+ ($innxmit_afail_host{$key} +
+ $innxmit_hiload{$key} + $innxmit_nospace{$key} +
+ $innxmit_cfail_host{$key} +
+ $innxmit_expire{$key} +
+ $innxmit_crefused{$key})) / $innxmit_site{$key} : 0";
+ total "total(%innxmit_site) ?
+ 100 * (total(%innxmit_site) -
+ (total(%innxmit_afail_host) +
+ total(%innxmit_hiload) +
+ total(%innxmit_nospace) +
+ total(%innxmit_cfail_host) +
+ total(%innxmit_expire) +
+ total(%innxmit_crefused))) / total(%innxmit_site) : 0";
+ };
+};
+
+section innxmit_unwanted {
+ title "Sites fed by innxmit rejecting bad articles:";
+ data "%innxmit_badart";
+ sort "$innxmit_badart{$b} <=> $innxmit_badart{$a}";
+ column {
+ numbering true;
+ name "Server";
+ format "%-23.23s";
+ value "$key";
+ format_total "TOTAL: %-16.16s";
+ total "$num";
+ };
+ column {
+ name "Total";
+ format_name "%6s";
+ format "%6d";
+ value "$innxmit_badart{$key}";
+ total "total(%innxmit_badart)";
+ };
+ column {
+ name "Group";
+ format_name "%6s";
+ format "%6d";
+ value "$innxmit_uw_ng_s{$key}";
+ total "total(%innxmit_uw_ng_s)";
+ };
+ column {
+ name "Dist";
+ format_name "%5s";
+ format "%5d";
+ value "$innxmit_uw_dist_s{$key}";
+ total "total(%innxmit_uw_dist_s)";
+ };
+ column {
+ name "Duplic";
+ format_name "%6s";
+ format "%6d";
+ value "$innxmit_duplicate{$key}";
+ total "total(%innxmit_duplicate)";
+ };
+ column {
+ name "Unapp";
+ format_name "%5s";
+ format "%5d";
+ value "$innxmit_unapproved{$key}";
+ total "total(%innxmit_unapproved)";
+ };
+ column {
+ name "TooOld";
+ format_name "%6s";
+ format "%6d";
+ value "$innxmit_tooold{$key}";
+ total "total(%innxmit_tooold)";
+ };
+ column {
+ name "Site";
+ format_name "%4s";
+ format "%4d";
+ value "$innxmit_uw_site{$key}";
+ total "total(%innxmit_uw_site)";
+ };
+ column {
+ name "Line";
+ format_name "%4s";
+ format "%4d";
+ value "$innxmit_linecount{$key}";
+ total "total(%innxmit_linecount)";
+ };
+ column {
+ name "Other";
+ format_name "%5s";
+ format "%5d";
+ value "$innxmit_others{$key}";
+ total "total(%innxmit_others)";
+ };
+};
+
+section crosspost {
+ title "Crosspost stats:";
+ data "%crosspost";
+ column {
+ name "Events";
+ format "%-63.63s";
+ value "$key";
+ format_total "TOTAL: %-56.56s";
+ total "$num";
+ };
+ column {
+ name "Number";
+ value "$crosspost{$key}";
+ format "%7s";
+ total "total(%crosspost)";
+ };
+ column {
+ name "Num/min";
+ value "$crosspost_times{$key}";
+ format "%7s";
+ total "total(%crosspost_times)";
+ };
+};
+
+section batcher_elapsed {
+ title "UUCP batches created:";
+ data "%batcher_elapsed";
+ column {
+ name "Server";
+ format "%-41.41s";
+ value "$key";
+ format_total "TOTAL: %-34.34s";
+ total "$num";
+ };
+ column {
+ name "Offered";
+ format_name "%7s";
+ format "%7d";
+ value "$batcher_offered{$key}";
+ total "total(%batcher_offered)";
+ };
+ column {
+ name "Articles";
+ format_name "%8s";
+ format "%8d";
+ value "$batcher_articles{$key}";
+ total "total(%batcher_articles)";
+ };
+ column {
+ name "Size";
+ format "%10s";
+ value "bytes($batcher_bytes{$key})";
+ total "bytes(total(%batcher_bytes))";
+ };
+ column {
+ name "Elapsed";
+ format "%9s";
+ value "time($batcher_elapsed{$key})";
+ total "time(total(%batcher_elapsed))";
+ };
+};
+
+section rnews_host {
+ title "Rnews articles offered from:";
+ data "%rnews_host";
+ sort "$rnews_host{$b} <=> $rnews_host{$a}";
+ column {
+ name "System";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Offered";
+ format_name "%7s";
+ format "%7d";
+ value "$rnews_host{$key}";
+ total "total(%rnews_host)";
+ };
+};
+
+section rnews_rejected {
+ title "Rnews connections rejected:";
+ data "%rnews_rejected";
+ sort "$rnews_rejected{$b} <=> $rnews_rejected{$a}";
+ column {
+ name "Reason";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%7s";
+ format "%7d";
+ value "$rnews_rejected{$key}";
+ total "total(%rnews_rejected)";
+ };
+};
+
+section rnews_misc {
+ title "Miscellaneous rnews statistics:";
+ data "%rnews_misc";
+ sort "$rnews_misc{$b} <=> $rnews_misc{$a}";
+ double true;
+ column {
+ primary true;
+ name "Event";
+ format "%-69.69s";
+ value "$key1";
+ format_total "TOTAL: %-62.62s";
+ total "";
+ };
+ column {
+ name "Element";
+ format " %-67.67s";
+ value "$key2";
+ total "";
+ };
+ column {
+ name "Number";
+ format_name "%9s";
+ format "%9d";
+ value "$rnews_misc{$key1}{$key2}";
+ total "total(%rnews_misc)";
+ };
+};
+
+section nnrpd_groups {
+ title "NNRP readership statistics:";
+ data "%nnrpd_articles";
+ sort "$nnrpd_articles{$b} <=> $nnrpd_articles{$a}";
+ numbering true;
+ column {
+ name "System";
+ format "%-30.30s";
+ value "$key";
+ format_total "TOTAL: %-23.23s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%4s";
+ format "%4d";
+ value "$nnrpd_connect{$key}";
+ total "total(%nnrpd_connect)";
+ };
+ column {
+ name "Arts";
+ format_name "%6s";
+ format "%6d";
+ value "$nnrpd_articles{$key}";
+ total "total(%nnrpd_articles)";
+ };
+ column {
+ name "Size";
+ format "%9s";
+ value "bytes($nnrpd_bytes{$key})";
+ total "bytes(total(%nnrpd_bytes))";
+ };
+ column {
+ name "Groups";
+ format_name "%6s";
+ format "%6d";
+ value "$nnrpd_groups{$key}";
+ total "total(%nnrpd_groups)";
+ };
+ column {
+ name "Post";
+ format_name "%4s";
+ format "%4d";
+ value "$nnrpd_post_ok{$key}";
+ total "total(%nnrpd_post_ok)";
+ };
+ column {
+ name "Rej";
+ format_name "%4s";
+ format "%4d";
+ value "$nnrpd_post_rej{$key} +
+ $nnrpd_post_error{$key}";
+ total "total(%nnrpd_post_rej) +
+ total(%nnrpd_post_error)";
+ };
+ column {
+ name "Elapsed";
+ format "%9s";
+ value "time($nnrpd_times{$key})";
+ total "time(total(%nnrpd_times))";
+ };
+};
+
+section nnrpd_dom_groups {
+ title "NNRP readership statistics (by domain):";
+ data "%nnrpd_dom_connect";
+ sort "$nnrpd_dom_articles{$b} <=> $nnrpd_dom_articles{$a}";
+ numbering true;
+ column {
+ name "System";
+ format "%-30.30s";
+ value "$key";
+ format_total "TOTAL: %-23.23s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%4s";
+ format "%4d";
+ value "$nnrpd_dom_connect{$key}";
+ total "total(%nnrpd_dom_connect)";
+ };
+ column {
+ name "Arts";
+ format_name "%6s";
+ format "%6d";
+ value "$nnrpd_dom_articles{$key}";
+ total "total(%nnrpd_dom_articles)";
+ };
+ column {
+ name "Size";
+ format "%9s";
+ value "bytes($nnrpd_dom_bytes{$key})";
+ total "bytes(total(%nnrpd_dom_bytes))";
+ };
+ column {
+ name "Groups";
+ format_name "%6s";
+ format "%6d";
+ value "$nnrpd_dom_groups{$key}";
+ total "total(%nnrpd_dom_groups)";
+ };
+ column {
+ name "Post";
+ format_name "%4s";
+ format "%4d";
+ value "$nnrpd_dom_post_ok{$key}";
+ total "total(%nnrpd_dom_post_ok)";
+ };
+ column {
+ name "Rej";
+ format_name "%4s";
+ format "%4d";
+ value "$nnrpd_dom_post_rej{$key} +
+ $nnrpd_dom_post_error{$key}";
+ total "total(%nnrpd_dom_post_rej) +
+ total(%nnrpd_dom_post_error)";
+ };
+ column {
+ name "Elapsed";
+ format "%9s";
+ value "time($nnrpd_dom_times{$key})";
+ total "time(total(%nnrpd_dom_times))";
+ };
+};
+
+section nnrpd_auth {
+ title "NNRP auth users:";
+ data "%nnrpd_auth";
+ top 20;
+ sort "$nnrpd_auth{$b} <=> $nnrpd_auth{$a}";
+ column {
+ name "User";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%7s";
+ format "%7d";
+ value "$nnrpd_auth{$key}";
+ total "total(%nnrpd_auth)";
+ };
+};
+
+section nnrpd_resource {
+ title "NNRP total resource statistics:";
+ data "%nnrpd_resource_elapsed";
+ top 20;
+ sort "$nnrpd_resource_elapsed{$b} <=> $nnrpd_resource_elapsed{$a}";
+ column {
+ name "System";
+ format "%-40.40s";
+ format_total "TOTAL: %-33.33s";
+ value "$key";
+ total "$num";
+ };
+ column {
+ name "User(ms)";
+ format_name "%9s";
+ format "%9.3f";
+ value "$nnrpd_resource_user{$key}";
+ total "total(%nnrpd_resource_user)";
+ };
+ column {
+ name "System(ms)";
+ format_name "%9s";
+ format "%9.3f";
+ value "$nnrpd_resource_system{$key}";
+ total "total(%nnrpd_resource_system)";
+ };
+ column {
+ name "Idle(ms)";
+ format_name "%9s";
+ format "%9.3f";
+ value "$nnrpd_resource_idle{$key}";
+ total "total(%nnrpd_resource_idle)";
+ };
+ column {
+ name "Elapsed";
+ format_name "%8s";
+ format "%9s";
+ value "time($nnrpd_resource_elapsed{$key})";
+ total "time(total(%nnrpd_resource_elapsed))";
+ };
+};
+
+section nnrpd_curious {
+ title "Curious NNRP server explorers:";
+ data "%nnrpd_curious";
+ top 20;
+ sort "$nnrpd_curious{$b} <=> $nnrpd_curious{$a}";
+ column {
+ name "System";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%7s";
+ format "%7d";
+ value "$nnrpd_curious{$key}";
+ total "total(%nnrpd_curious)";
+ };
+};
+
+section nnrpd_no_permission {
+ title "NNRP no permission clients:";
+ data "%nnrpd_no_permission";
+ sort "$nnrpd_no_permission{$b} <=> $nnrpd_no_permission{$a}";
+ column {
+ name "System";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%7s";
+ format "%7d";
+ value "$nnrpd_no_permission{$key}";
+ total "total(%nnrpd_no_permission)";
+ };
+};
+
+section nnrpd_gethostbyaddr {
+ title "NNRP gethostbyaddr failures:";
+ data "%nnrpd_gethostbyaddr";
+ top 20;
+ sort "$nnrpd_gethostbyaddr{$b} <=> $nnrpd_gethostbyaddr{$a}";
+ column {
+ name "System";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%7s";
+ format "%7d";
+ value "$nnrpd_gethostbyaddr{$key}";
+ total "total(%nnrpd_gethostbyaddr)";
+ };
+};
+
+section nnrpd_unrecognized {
+ title "NNRP unrecognized commands (by host):";
+ data "%nnrpd_unrecognized";
+ sort "$nnrpd_unrecognized{$b} <=> $nnrpd_unrecognized{$a}";
+ column {
+ name "System";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%7s";
+ format "%7d";
+ value "$nnrpd_unrecognized{$key}";
+ total "total(%nnrpd_unrecognized)";
+ };
+};
+
+section nnrpd_unrecognized2 {
+ title "NNRP unrecognized commands (by command):";
+ data "%nnrpd_unrecogn_cmd";
+ sort "$nnrpd_unrecogn_cmd{$b} <=> $nnrpd_unrecogn_cmd{$a}";
+ column {
+ name "Command";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%7s";
+ format "%7d";
+ value "$nnrpd_unrecogn_cmd{$key}";
+ total "total(%nnrpd_unrecogn_cmd)";
+ };
+};
+
+section nnrpd_timeout {
+ title "NNRP client timeouts:";
+ data "%nnrpd_timeout";
+ top 20;
+ sort "$nnrpd_timeout{$b} <=> $nnrpd_timeout{$a}";
+ column {
+ name "System";
+ format "%-67.67s";
+ value "$key";
+ format_total "TOTAL: %-60.60s";
+ total "$num";
+ };
+ column {
+ name "Conn";
+ format_name "%5s";
+ format "%5d";
+ value "$nnrpd_timeout{$key}";
+ total "total(%nnrpd_timeout)";
+ };
+ column {
+ name "Peer";
+ format_name "%5s";
+ format "%5d";
+ value "$nnrpd_reset_peer{$key}";
+ total "total(%nnrpd_reset_peer)";
+ };
+};
+
+section nnrpd_hierarchy {
+ title "Newsgroup request counts (by category):";
+ data "%nnrpd_hierarchy";
+ sort "$nnrpd_hierarchy{$b} <=> $nnrpd_hierarchy{$a}";
+ numbering true;
+ column {
+ name "Category";
+ format "%-64.64s";
+ value "$key";
+ format_total "TOTAL: %-57.57s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%7s";
+ format "%7d";
+ value "$nnrpd_hierarchy{$key}";
+ total "total(%nnrpd_hierarchy)";
+ };
+ column {
+ name "Pct";
+ format_name "%6s";
+ format "%5.1f%%";
+ value "$nnrpd_hierarchy{$key} /
+ total(%nnrpd_hierarchy) * 100";
+ total "100";
+ };
+ # graph : type piechart
+};
+
+section nnrpd_group {
+ title "Newsgroup request counts (by newsgroup):";
+ data "%nnrpd_group";
+ sort "$nnrpd_group{$b} <=> $nnrpd_group{$a}";
+ top 100;
+ numbering true;
+ column {
+ name "Newsgroup";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Count";
+ format_name "%7s";
+ format "%7d";
+ value "$nnrpd_group{$key}";
+ total "total(%nnrpd_group)";
+ };
+};
+
+section ihave_site {
+ title "IHAVE messages offered from:";
+ data "%controlchan_ihave_site";
+ sort "$controlchan_ihave_site{$b} <=> $controlchan_ihave_site{$a}";
+ column {
+ name "System";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Offered";
+ format_name "%7s";
+ format "%7d";
+ value "$controlchan_ihave_site{$key}";
+ total "total(%controlchan_ihave_site)";
+ };
+};
+
+section sendme_site {
+ title "SENDME messages offered from:";
+ data "%controlchan_sendme_site";
+ sort "$controlchan_sendme_site{$b} <=>
+ $controlchan_sendme_site{$a}";
+ column {
+ name "System";
+ format "%-71.71s";
+ value "$key";
+ format_total "TOTAL: %-64.64s";
+ total "$num";
+ };
+ column {
+ name "Offered";
+ format_name "%7s";
+ format "%7d";
+ value "$controlchan_sendme_site{$key}";
+ total "total(%controlchan_sendme_site)";
+ };
+};
--- /dev/null
+#! /usr/bin/perl
+# fixscript will replace this line with require innshellvars.pl
+
+##########################################################################
+#
+# innreport: Perl script to summarize news log files
+# (with optional HTML output and graphs).
+#
+# version: 3.0.2
+#
+# Copyright (c) 1996-1999, Fabien Tassin (fta@sofaraway.org).
+#
+##########################################################################
+#
+# Usage: innreport -f config_file [-[no]options] logfile [logfile2 [...]]
+# where options are:
+# -h (or -help) : this help page
+# -html : HTML output
+# -v : display the version number of INNreport
+# -f config_file : name of the configuration file
+# -config : print INNreport configuration information
+# -g : want graphs [default]
+# -graph : an alias for option -g
+# -d directory : directory for Web pages
+# -dir directory : an alias for option -d
+# -p directory : pictures path (file space)
+# -path directory : an alias for option -p
+# -w directory : pictures path (web space)
+# -webpath directory : an alias for option -w
+# -i : name of index page
+# -index : an alias for option -i
+# -a : want to archive HTML results
+# -archive : an alias for option -a
+# -c number : how many report files to keep (0 = all)
+# -cycle number : an alias for option -c
+# -s char : separator for filename
+# -separator char : an alias for option -s
+# -unknown : Unknown entries from news log file
+# -maxunrec : Max number of unrecognized line to display
+# -casesensitive : Case sensitive
+# -notdaily : Never perform daily actions
+#
+# Use no in front of boolean options to unset them.
+# For example, "-html" is set by default. Use "-nohtml" to remove this
+# feature.
+#
+##########################################################################
+#
+# ABSOLUTELY NO WARRANTY WITH THIS PACKAGE. USE IT AT YOUR OWN RISKS.
+#
+# Note: You need the Perl graphic library GD.pm if you want the graphs.
+# GD is available on all good CPAN ftp sites:
+# ex: [CPAN_DIR]/authors/id/LDS/GD-1.1_.tar.gz (or greater)
+# or directly to:
+# <URL:http://www-genome.wi.mit.edu/pub/software/WWW/GD.html>
+# Note : innreport will create PNG or GIF files depending upon
+# the GD version.
+#
+# Documentation: for a short explaination of the different options, you
+# can read the usage (obtained with the -h or -help switch).
+#
+# Install: - check the Perl location (first line). Require Perl 5.002
+# or greater.
+# - look at the parameters in the configuration file (section
+# 'default')
+# - copy the configuration file into ${PATHETC}/innreport.conf
+# - copy the INN module into ${PATHETC}/innreport_inn.pm
+# - copy this script into ${PATHETC}/innreport
+# - be sure that the news user can run it (chmod 755 or 750)
+# - in "scanlog", comment the line containing innlog and add:
+# ${PATHETC}/innreport -f ${PATHETC}/innreport.conf ${OLD_SYSLOG}
+# or, if you want to change some options:
+# ${PATHETC}/innreport -f ${PATHETC}/innreport.conf options ${OLD_SYSLOG}
+#
+# Report: please report bugs (preferably) to the INN mailing list
+# (see README) or directly to the author (do not forget to
+# include the result of the "-config" switch, the parameters
+# passed on the command line and the INN version).
+# Please also report unknown entries.
+# Be sure your are using the latest version of this script before
+# any report.
+#
+##########################################################################
+
+# Note: References to <ftp://ftp.sofaraway.org/pub/innreport/> have been
+# removed from the output because this site appears to no longer exist. It
+# used to be the upstream source for innreport. If there is a new site for
+# innreport releases, please notify the INN maintainers.
+
+# remember to add '-w' on the first line and to uncomment the 'use strict'
+# below before doing any changes to this file.
+
+use strict;
+
+## Do you want to create a Web page. Pick DO or DONT.
+my $HTML = "DO";
+
+## Do you want the graphs (need $HTML too). Pick DO or DONT.
+my $GRAPH = "DO";
+
+## Directory for the Web pages (used only if the previous line is active)
+my $HTML_dir = "$inn::pathhttp";
+
+## Directory for the pictures (need HTML support) in the file space
+my $IMG_dir = "$HTML_dir/pics";
+
+## Directory for the pictures (need HTML support) in the Web space
+## (can be relative or global)
+my $IMG_pth = "pics";
+
+## Do you want to archive HTML results (& pics) [ will add a date in each
+## name ]. Pick DO or DONT.
+my $ARCHIVE = "DO";
+
+## index page will be called:
+my $index = "index.html";
+
+## How many report files to keep (0 = all) (need $ARCHIVE).
+my $CYCLE = 0;
+
+## separator between hours-minutes-seconds in filenames
+## (normaly a ":" but some web-browsers (Lynx, MS-IE, Mosaic) can't read it)
+## Warning: never use "/". Use only a _valid_ filename char.
+my $SEPARATOR = ".";
+
+## Do you want the "Unknown entries from news log file" report. Pick DO or
+## DONT.
+my $WANT_UNKNOWN = "DO";
+
+## Max number of unrecognized lines to display (if $WANT_UNKNOWN)
+## (-1 = no limit)
+my $MAX_UNRECOGNIZED = 50;
+
+## Do you want to be case sensitive. Pick DO or DONT.
+my $CASE_SENSITIVE = "DO";
+
+## Some actions must only be performed daily (once for a log file).
+## (ex: unwanted.log with INN). Default value (DONT) means to perform
+## these actions each . Pick DO or DONT.
+my $NOT_DAILY = "DONT";
+
+###############################################
+## THERE'S NOTHING TO CHANGE AFTER THIS LINE ##
+###############################################
+
+my $version = "3.0.2";
+my %output; # content of the configuration file.
+my $DEBUG = 0; # set to 1 to verify the structure/content of the conf file.
+my $start_time = time;
+
+# Require Perl 5.002 or greater.
+require 5.002;
+use Getopt::Long;
+use vars qw/$HAVE_GD $GD_FORMAT/;
+
+my @old_argv = @ARGV;
+
+# Convert DO/DONT into boolean values.
+{
+ my $i;
+ foreach $i (\$HTML, \$GRAPH, \$ARCHIVE, \$WANT_UNKNOWN,
+ \$CASE_SENSITIVE, \$NOT_DAILY) {
+ $$i = $$i eq 'DO' ? 1 : 0 ;
+ }
+}
+
+my %ref;
+GetOptions (\%ref,
+ qw(-h -help
+ -html!
+ -config
+ -f=s
+ -g! -graph!
+ -d=s -dir=s
+ -p=s -path=s
+ -w=s -webpath=s
+ -i=s -index=s
+ -a! -archive!
+ -c=i -cycle=i
+ -s=s -separator=s
+ -unknown!
+ -html-unknown!
+ -maxunrec=i
+ -casesensitive!
+ -notdaily!
+ -v
+ ));
+
+&Version if $ref{'v'};
+
+&Decode_Config_File($ref{'f'}) if defined $ref{'f'};
+&Usage if $ref{'h'} || $ref{'help'} || !defined $ref{'f'};
+
+$HTML = 0 if defined $output{'default'}{'html'};
+$HTML = 1 if $output{'default'}{'html'} eq 'true';
+$HTML = 0 if defined $ref{'html'};
+$HTML = 1 if $ref{'html'};
+
+$GRAPH = 0 if defined $output{'default'}{'graph'};
+$GRAPH = 1 if $HTML && ($output{'default'}{'graph'} eq 'true');
+$GRAPH = 0 if defined $ref{'g'} || defined $ref{'graph'};
+$GRAPH = 1 if $HTML && ($ref{'g'} || $ref{'graph'});
+
+$HTML_dir = &GetValue ($output{'default'}{'html_dir'})
+ if defined $output{'default'}{'html_dir'};
+$HTML_dir = $ref{'d'} if defined $ref{'d'};
+$HTML_dir = $ref{'dir'} if defined $ref{'dir'};
+
+$IMG_pth = &GetValue ($output{'default'}{'img_dir'})
+ if defined $output{'default'}{'img_dir'};
+$IMG_pth = $ref{'w'} if defined $ref{'w'};
+$IMG_pth = $ref{'webpath'} if defined $ref{'webpath'};
+
+$IMG_dir = $HTML_dir . "/" . $IMG_pth
+ if (defined $output{'default'}{'html_dir'} ||
+ defined $ref{'w'} || defined $ref{'webpath'})
+ &&
+ (defined $output{'default'}{'html_dir'} ||
+ defined $ref{'d'} || defined $ref{'dir'});
+
+$IMG_dir = $ref{'p'} if defined $ref{'p'};
+$IMG_dir = $ref{'path'} if defined $ref{'path'};
+
+$index = &GetValue ($output{'default'}{'index'})
+ if defined $output{'default'}{'index'};
+$index = $ref{'i'} if defined $ref{'i'};
+$index = $ref{'index'} if defined $ref{'index'};
+
+$ARCHIVE = &GetValue ($output{'default'}{'archive'})
+ if defined $output{'default'}{'archive'};
+$ARCHIVE = $ARCHIVE eq 'true';
+$ARCHIVE = 0 if defined $ref{'a'} || defined $ref{'archive'};
+$ARCHIVE = 1 if ($ref{'a'} || $ref{'archive'}) && $HTML;
+$ARCHIVE = 0 unless $HTML;
+
+$CYCLE = &GetValue ($output{'default'}{'cycle'})
+ if defined $output{'default'}{'cycle'};
+$CYCLE = 0 if $CYCLE eq 'none';
+$CYCLE = $ref{'c'} if defined $ref{'c'};
+$CYCLE = $ref{'cycle'} if defined $ref{'cycle'};
+
+$SEPARATOR = &GetValue ($output{'default'}{'separator'})
+ if defined $output{'default'}{'separator'};
+$SEPARATOR = $ref{'s'} if defined $ref{'s'};
+$SEPARATOR = $ref{'separator'} if defined $ref{'separator'};
+
+if (defined $output{'default'}{'unknown'}) {
+ $WANT_UNKNOWN = &GetValue ($output{'default'}{'unknown'});
+ $WANT_UNKNOWN = $WANT_UNKNOWN eq 'true' ? 1 : 0;
+}
+$WANT_UNKNOWN = 0 if defined $ref{'unknown'};
+$WANT_UNKNOWN = 1 if $ref{'unknown'};
+
+my $WANT_HTML_UNKNOWN = $WANT_UNKNOWN;
+if (defined $output{'default'}{'html-unknown'}) {
+ $WANT_HTML_UNKNOWN = &GetValue ($output{'default'}{'html-unknown'});
+ $WANT_HTML_UNKNOWN = $WANT_HTML_UNKNOWN eq 'true' ? 1 : 0;
+}
+$WANT_HTML_UNKNOWN = 0 if defined $ref{'html-unknown'};
+$WANT_HTML_UNKNOWN = 1 if $ref{'html-unknown'};
+
+$NOT_DAILY = 0 if defined $ref{'notdaily'};
+$NOT_DAILY = 1 if $ref{'notdaily'};
+
+$MAX_UNRECOGNIZED = &GetValue ($output{'default'}{'max_unknown'})
+ if defined $output{'default'}{'max_unknown'};
+$MAX_UNRECOGNIZED = $ref{'maxunrec'} if defined ($ref{'maxunrec'});
+
+$CASE_SENSITIVE = &GetValue ($output{'default'}{'casesensitive'})
+ if defined $output{'default'}{'casesensitive'};
+$CASE_SENSITIVE = 1 if $CASE_SENSITIVE eq 'true';
+$CASE_SENSITIVE = 0 if defined $ref{'casesensitive'};
+$CASE_SENSITIVE = 1 if $ref{'casesensitive'};
+
+my $CLASS = &GetValue ($output{'default'}{'module'});
+my $LIBPATH = &GetValue ($output{'default'}{'libpath'});
+
+umask 022;
+
+BEGIN {
+ eval "use GD;";
+ $HAVE_GD = $@ eq '';
+ if ($HAVE_GD) {
+ my $gd = new GD::Image(1,1);
+ $GD_FORMAT = "gif" if $gd->can('gif');
+ $GD_FORMAT = "png" if $gd->can('png');
+ }
+ $HAVE_GD;
+};
+undef $GRAPH unless $HTML;
+if ($GRAPH && !$::HAVE_GD) {
+ print "WARNING: can't make graphs as required.\n" .
+ " Install GD.pm or disable this option.\n\n";
+ undef $GRAPH;
+}
+
+if ($HTML) {
+ if ($GRAPH) {
+ $IMG_dir = "." if defined $IMG_dir && $IMG_dir eq '';
+ $IMG_pth .= "/" if $IMG_pth;
+ $IMG_pth =~ s|/+|/|g;
+ $IMG_dir =~ s|/+|/|g;
+ unless (-w $IMG_dir) {
+ print "WARNING: can't write in \"$IMG_dir\" as required by -g " .
+ "switch.\n Option -g removed. Please see the -p switch.\n\n";
+ undef $GRAPH;
+ }
+ }
+ $HTML_dir = "." if defined $HTML_dir && $HTML_dir eq '';
+ unless (-w $HTML_dir) {
+ print "WARNING: can't write in \"$HTML_dir\" as required by -html " .
+ "switch.\n Option -html and -a removed. Please see the " .
+ "-d switch.\n\n";
+ undef $HTML;
+ $ARCHIVE = 0;
+ }
+}
+
+# Now, we are sure that HTML and graphs can be made if options are active.
+&Summary if defined $ref{'config'};
+
+my $unrecognize_max = 0;
+my @unrecognize;
+my ($total_line, $total_size) = (0, 0);
+my ($suffix, $HTML_output, %config, $first_date, $last_date,
+ %prog_type, %prog_size);
+
+my $HTML_header = '';
+my $HTML_footer = '';
+
+my $MIN = 1E10;
+my $MAX = -1;
+
+my $xmax = &GetValue ($output{'default'}{'graph_width'}) # Graph size..
+ if defined $output{'default'}{'graph_width'};
+$xmax = 550 unless $xmax;
+
+my $transparent = &GetValue ($output{'default'}{'transparent'})
+ if defined $output{'default'}{'transparent'};
+$transparent = (defined $transparent && $transparent eq 'true') ? 1 : 0;
+
+my $repeated = 1;
+
+my $first_date_cvt = $MIN;
+my $last_date_cvt = $MAX;
+
+
+#########################################################################
+my $s = sprintf "use lib qw($LIBPATH); use $CLASS;";
+eval $s; # initialization
+die "Can't find/load $CLASS.pm : $@\n" if $@;
+
+my $save_line = <>;
+$_ = $save_line;
+local $^W = 0 if $] < 5.004; # to avoid a warning for each '+=' first use.
+LINE: while (!eof ()) {
+ $total_line++;
+ my $size = length;
+ $total_size += $size;
+
+ # Syslog optimization
+ if ($repeated) {
+ $repeated--;
+ $_ = $save_line;
+ }
+ else {
+ $_ = <>;
+ if ($_ =~ /last message repeated (\d+) times?$/o) {
+ $repeated = $1;
+ $_ = $save_line;
+ }
+ else {
+ $save_line = $_;
+ }
+ }
+
+ # skip empty lines
+ next LINE if $_ eq '';
+
+ my $res;
+ my ($day, $hour, $prog, $left) =
+ $_ =~ m/^(\S+\s+\S+) (\S+) \S+ (\S+): \[ID \d+ \S+\] (.*)$/o;
+ ($day, $hour, $prog, $left) =
+ $_ =~ m/^(\S+\s+\S+) (\S+) \S+ (\S+): (.*)$/o unless $day;
+ ($day, $hour, $prog, $left) =
+ $_ =~ m/^(\S+\s+\S+) (\S+) \d+ \S+ (\S+): (.*)$/o unless $day;
+
+ unless ($day) {
+ ($day, $hour, $res, $left) = $_ =~ m/^(\S+\s+\S+) (\S+)\.\d+ (\S+) (.*)$/o;
+ if ($day) {
+ my $cvtdate = &ConvDate ("$day $hour");
+ if ($cvtdate < $first_date_cvt) {
+ $first_date_cvt = $cvtdate;
+ $first_date = "$day $hour";
+ }
+ elsif ($cvtdate > $last_date_cvt) {
+ $last_date_cvt = $cvtdate;
+ $last_date = "$day $hour";
+ }
+ $prog = "inn";
+ }
+ else {
+ next if $_ =~ /^$/;
+ # Unrecognize line... skip
+ $unrecognize[$unrecognize_max] = $_
+ unless $unrecognize_max > $MAX_UNRECOGNIZED
+ && $MAX_UNRECOGNIZED > 0;
+ $unrecognize_max++;
+ next LINE;
+ }
+ }
+ else {
+ my $cvtdate = &ConvDate ("$day $hour");
+ if ($cvtdate < $first_date_cvt) {
+ $first_date_cvt = $cvtdate;
+ $first_date = "$day $hour";
+ }
+ elsif ($cvtdate > $last_date_cvt) {
+ $last_date_cvt = $cvtdate;
+ $last_date = "$day $hour";
+ }
+ }
+
+ ########
+ ## Program name
+ # word[7164] -> word
+ my ($pid) = $prog =~ s/\[(\d+)\]$//o;
+ # word: -> word
+ $prog =~ s/:$//o;
+ # wordX -> word (where X is a digit)
+ $prog =~ s/\d+$//o;
+
+ $prog_type{$prog}++;
+ $prog_size{$prog} = 0 unless defined $prog_size{$prog}; # stupid warning :(
+ $prog_size{$prog} += $size;
+
+ # The "heart" of the tool.
+ {
+ no strict;
+ next LINE if
+ &{$CLASS."::collect"} ($day, $hour, $prog, $res, $left, $CASE_SENSITIVE);
+ }
+
+ $unrecognize[$unrecognize_max] = $_
+ unless $unrecognize_max > $MAX_UNRECOGNIZED
+ && $MAX_UNRECOGNIZED > 0;
+ $unrecognize_max++;
+}
+
+{
+ no strict;
+ &{$CLASS . "::adjust"} ($first_date, $last_date);
+}
+
+$| = 1;
+
+die "no data. Abort.\n" unless $total_line;
+
+my $sec_glob = &ConvDate ("$last_date") - &ConvDate ("$first_date");
+unless ($sec_glob) {
+ print "WARNING: bad date (\"$last_date\" or \"$first_date\")\n" .
+ " Please, contact the author of innreport.\n";
+ $sec_glob = 24 * 60 * 60; # one day
+}
+
+$HTML_output = '';
+
+if ($HTML) {
+ # Create a new filename (unique and _sortable_)
+ if ($ARCHIVE) {
+ # The filename will contain the first date of the log or the current time.
+ my ($ts, $tm, $th, $dd, $dm, $dy) = localtime;
+ my ($m, $d, $h, $mn, $s) =
+ $first_date =~ /^(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)$/;
+ if ($m) {
+ my $ddm = (index "JanFebMarAprMayJunJulAugSepOctNovDec", $m) / 3;
+ # Adjust the year because syslog doesn't record it. We assume that
+ # it's the current year unless the last date is in the future.
+ my $ld = &ConvDate($last_date);
+ $dy-- if $ld > $ts + 60 * ($tm + 60 * ($th + 24 * ($dd - 1 +
+ substr("000031059090120151181212243273304334", $dm * 3, 3)))) ||
+ $ld < &ConvDate($first_date);
+ ($dm, $dd, $th, $tm, $ts) = ($ddm, $d, $h, $mn, $s);
+ }
+ $dm++; # because January = 0 and we prefer 1
+ $dy += 100 if $dy < 90; # Try to pacify the year 2000 !
+ $dy += 1900;
+ $suffix = sprintf ".%02d.%02d.%02d-%02d$SEPARATOR%02d$SEPARATOR%02d",
+ $dy, $dm, $dd, $th, $tm, $ts;
+ }
+ else {
+ $suffix = '';
+ }
+ $HTML_output = "$HTML_dir" . "/news-notice" . "$suffix" . ".html";
+ $HTML_output =~ s|/+|/|g;
+ if (defined $output{'default'}{'html_header_file'}) {
+ my $file = &GetValue ($output{'default'}{'html_header_file'});
+ $file = $HTML_dir . "/" . $file;
+ open (F, $file) && do {
+ local $/ = undef;
+ $HTML_header = <F>;
+ close F;
+ };
+ }
+ if (defined $output{'default'}{'html_footer_file'}) {
+ my $file = &GetValue ($output{'default'}{'html_footer_file'});
+ $file = $HTML_dir . "/" . $file;
+ open (F, $file) && do {
+ local $/ = undef;
+ $HTML_footer = <F>;
+ close F;
+ };
+ }
+}
+
+&Write_all_results ($HTML_output, \%output);
+
+&Make_Index ($HTML_dir, $index, "news-notice$suffix.html", \%output)
+ if $HTML && $index;
+
+#====================================================================
+
+if ($ARCHIVE) {
+ # rotate html files
+ &Rotate ($CYCLE, $HTML_dir, "news-notice", ".html");
+
+ # rotate pictures
+ my $report;
+ foreach $report (@{$output{'_order_'}}) {
+ next if $report =~ m/^(default|index)$/;
+ next unless defined $output{$report}{'graph'};
+
+ my $i = 0;
+ while ($GRAPH && defined ${${$output{$report}{'graph'}}[$i]}{'type'}) {
+ my $name = $report . ($i ? $i : '');
+ &Rotate ($CYCLE, $IMG_dir, $name, '.' . $GD_FORMAT);
+ $i++;
+ }
+ }
+}
+
+# Code needed by INN only. It must be in innreport_inn.pm to keep things clean.
+if (!$NOT_DAILY && defined $output{'default'}{'unwanted_log'}) {
+ my $logfile = &GetValue ($output{'default'}{'unwanted_log'});
+ my $logpath = &GetValue ($output{'default'}{'logpath'});
+ {
+ no strict;
+ &{$CLASS . "::report_unwanted_ng"} ("$logpath/$logfile");
+ }
+}
+
+################
+# End of report.
+###################################################################
+
+######
+# Misc...
+
+# Compare 2 dates (+hour)
+sub DateCompare {
+ # ex: "May 12 06" for May 12, 6:00am
+ local $[ = 0;
+ # The 2 dates are near. The range is less than a few days that's why we
+ # can cheat to determine the order. It is only important if one date
+ # is in January and the other in December.
+
+ my $date1 = substr ($a, 4, 2) * 24;
+ my $date2 = substr ($b, 4, 2) * 24;
+ $date1 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($a,0,3)) * 288;
+ $date2 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($b,0,3)) * 288;
+ if ($date1 - $date2 > 300 * 24) {
+ $date2 += 288 * 3 * 12;
+ }
+ elsif ($date2 - $date1 > 300 * 24) {
+ $date1 += 288 * 3 * 12;
+ }
+ $date1 += substr($a, 7, 2);
+ $date2 += substr($b, 7, 2);
+ $date1 - $date2;
+}
+
+
+# Convert: seconds to hh:mm:ss
+sub second2time {
+ my $temp;
+ my $t = shift;
+ # Hours
+ $temp = sprintf "%02d", $t / 3600;
+ my $chaine = "$temp:";
+ $t %= 3600;
+ # Min
+ $temp = sprintf "%02d", $t / 60;
+ $chaine .= "$temp:";
+ $t %= 60;
+ # Sec
+ $chaine .= sprintf "%02d", $t;
+ return $chaine;
+}
+
+# Convert: milliseconds to hh:mm:ss:mm
+sub ms2time {
+ my $temp;
+ my $t = shift;
+ # Hours
+ $temp = sprintf "%02d", $t / 3600000;
+ my $chaine = "$temp:";
+ $t %= 3600000;
+ # Min
+ $temp = sprintf "%02d", $t / 60000;
+ $chaine .= "$temp:";
+ $t %= 60000;
+ # Sec
+ $temp = sprintf "%02d", $t / 1000;
+ $chaine .= "$temp.";
+ $t %= 1000;
+ # Millisec
+ $chaine .= sprintf "%03d", $t;
+ return $chaine;
+}
+
+# Rotate the archive files..
+sub Rotate {
+ # Usage: &Rotate ($max_files, "$directory", "prefix", "suffix");
+ my ($max, $rep, $prefix, $suffix) = @_;
+ my ($file, $num, %files);
+ local ($a, $b);
+
+ return 1 unless $max;
+ opendir (DIR, "$rep") || die "Error: Cant open directory \"$rep\"\n";
+
+ FILE : while (defined ($file = readdir (DIR))) {
+ next FILE
+ unless $file =~ /^ # e.g. news-notice.1997.05.14-01:34:29.html
+ $prefix # Prefix : news-notice
+ \. # dot : .
+ (\d\d)?\d\d # Year : 1997 (or 97)
+ \. # dot : .
+ \d\d # Month : 05
+ \. # dot : .
+ \d\d # Day : 14
+ - # Separator : -
+ \d\d # Hour : 01
+ $SEPARATOR # Separator : ":"
+ \d\d # Minute : 34
+ $SEPARATOR # Separator : ":"
+ \d\d # Second : 29
+ $suffix # Suffix : ".html"
+ $/x;
+ $files{$file}++;
+ }
+ closedir DIR;
+ $num = 0;
+ foreach $file (sort {$b cmp $a} (keys (%files))) {
+ unlink "$rep/$file" if $num++ >= $max && -f "$rep/$file";
+ }
+ return 1;
+}
+
+# convert a date to a number of seconds
+sub ConvDate {
+ # usage: $num = &ConvDate ($date);
+ # date format is Aug 22 01:49:40
+ my $T = shift;
+ my ($m, $d, $h, $mn, $s) = $T =~ /^(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)$/;
+ my $out = $s + 60 * $mn + 3600 * $h + 86400 * ($d - 1);
+
+ $m = substr("000031059090120151181212243273304334",
+ index ("JanFebMarAprMayJunJulAugSepOctNovDec", $m), 3);
+ $out += $m * 86400;
+ return $out;
+}
+
+# Compare 2 filenames
+sub filenamecmp {
+ local $[ = 0;
+ my ($la, $lb) = ($a, $b);
+ my ($ya) = $la =~ m/news-notice\.(\d+)\./o;
+ $ya += 100 if $ya < 90; # Try to pacify the year 2000 !
+ $ya += 1900 if $ya < 1900; # xx -> xxxx
+ my ($yb) = $lb =~ m/news-notice\.(\d+)\./o;
+ $yb += 100 if $yb < 90; # Try to pacify the year 2000 !
+ $yb += 1900 if $yb < 1900; # xx -> xxxx
+
+ $la =~ s/news-notice\.(\d+)\./$ya\./;
+ $lb =~ s/news-notice\.(\d+)\./$yb\./;
+ $la =~ s/[\.\-\:html]//g;
+ $lb =~ s/[\.\-\:html]//g;
+
+ $lb <=> $la;
+}
+
+sub ComputeTotal {
+ my $h = shift;
+ my $total = 0;
+ my $key;
+ foreach $key (keys (%$h)) {
+ $total += $$h{$key};
+ }
+ $total;
+}
+
+sub ComputeTotalDouble {
+ my $h = shift;
+ my $total = 0;
+ my ($key1, $key2);
+ foreach $key1 (keys (%$h)) {
+ foreach $key2 (keys (%{$$h{$key1}})) {
+ $total += ${$$h{$key1}}{$key2};
+ }
+ }
+ $total;
+}
+
+# make an index for archive pages
+sub Make_Index {
+ my ($rep, $index, $filename, $data) = @_;
+ my %output = %$data;
+
+ $index =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+
+ # add requested data at the end of the database.
+ open (DATA, ">> $rep/innreport.db") || die "can't open $rep/innreport.db\n";
+ my $i = 0;
+ my $res = "$filename";
+ while (defined ${${$output{'index'}{'column'}}[$i]}{'value'}) {
+ my $data = &GetValue (${${$output{'index'}{'column'}}[$i]}{'value'});
+ $data =~ s/\n//sog;
+ my @list = split /\|/, $data;
+ my $val;
+ foreach $val (@list) {
+ $res .= ($val eq 'date' ? "|$first_date -- $last_date"
+ : "|" . &EvalExpr($val));
+ }
+ $i++;
+ }
+ print DATA "$res\n";
+ close DATA;
+
+ # sort the database (reverse order), remove duplicates.
+ open (DATA, "$rep/innreport.db") || die "can't open $rep/innreport.db\n";
+ my %data;
+ while (<DATA>) {
+ m/^([^\|]+)\|(.*)$/o;
+ $data{$1} = $2;
+ }
+ close DATA;
+ open (DATA, "> $rep/innreport.db") || die "can't open $rep/innreport.db\n";
+ $i = 0;
+ foreach (sort {$b cmp $a} (keys %data)) {
+ print DATA "$_|$data{$_}\n" if $CYCLE == 0 || $i < $CYCLE;
+ $i++;
+ }
+ close DATA;
+
+ my $title = "Daily Usenet report";
+ $title = &GetValue ($output{'default'}{'title'})
+ if defined $output{'default'}{'title'};
+ $title =~ s/\\\"/\"/g;
+ my $Title = $title;
+ $Title =~ s/<.*?>//g;
+ my $body = '';
+ $body = &GetValue ($output{'default'}{'html_body'})
+ if defined $output{'default'}{'html_body'};
+ $body =~ s/\\\"/\"/go;
+ my $result = sprintf <<EOF;
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>$Title: index</TITLE>
+</HEAD><BODY $body>
+$HTML_header
+<HR ALIGN=CENTER SIZE=\"4\" WIDTH=\"100%%\">
+<BR><CENTER><FONT SIZE=\"+2\">
+<B>$title - archives</B>
+</FONT></CENTER>
+<BR CLEAR=ALL>
+<HR ALIGN=CENTER SIZE=4 WIDTH=\"100%%\"><P>
+<CENTER>
+EOF
+
+ if ($GRAPH) {
+ my $i = 0;
+ while (defined ${${$output{'index'}{'graph'}}[$i]}{'title'}) {
+ my $title = &GetValue (${${$output{'index'}{'graph'}}[$i]}{'title'});
+ my $filename = "index$i.$GD_FORMAT";
+ my $color_bg = &GetValue (${${$output{'index'}{'graph'}}[$i]}{'color'});
+ my $unit = &GetValue (${${$output{'index'}{'graph'}}[$i]}{'unit'});
+ my $date_idx = &GetValue (${${$output{'index'}{'graph'}}[$i]}{'value'});
+ $date_idx =~ s/^val(\d+)$/$1/o;
+ my @c = @{${${$output{'index'}{'graph'}}[$i]}{'data'}};
+ my $label_in = &GetValue (${$c[0]}{'name'});
+ my $color_in = &GetValue (${$c[0]}{'color'});
+ my $value_in = &GetValue (${$c[0]}{'value'});
+ my $type_in = 0;
+ $type_in = $value_in =~ s/^byte\((.*?)\)$/$1/o;
+ $value_in =~ s/^val(\d+)$/$1/o;
+ my $label_out = &GetValue (${$c[1]}{'name'});
+ my $color_out = &GetValue (${$c[1]}{'color'});
+ my $value_out = &GetValue (${$c[1]}{'value'});
+ my $type_out = 0;
+ $type_out = $value_out =~ s/^byte\((.*?)\)$/$1/o;
+ $value_out =~ s/^val(\d+)$/$1/o;
+ my (%in, %out, %dates, $k);
+ foreach $k (keys (%data)) {
+ my @res = split /\|/, $data{$k};
+ my ($year) = $k =~ m/^news-notice\.(\d+)\.\d+\.\d+-\d+.\d+.\d+\.html/;
+ next unless $year; # bad filename.. strange.
+ my ($start, $end) =
+ $res[$date_idx - 1] =~ m/^(\w+\s+\d+ \S+) -- (\w+\s+\d+ \S+)$/o;
+ next unless $start; # bad date
+ $start = &ConvDate ($start);
+ $end = &ConvDate ($end);
+ # 31/12 - 1/1 ?
+ my $inc = $end < $start ? 1 : 0;
+ $start += (($year - 1970) * 365 +
+ int (($year - 1968) / 4)) * 3600 * 24;
+ $year += $inc;
+ $end += (($year - 1970) * 365 + int (($year - 1968) / 4)) * 3600 * 24;
+ $in{$start} = $type_in ? &kb2i($res[$value_in - 1])
+ : $res[$value_in - 1];
+ $out{$start} = $type_out ? &kb2i($res[$value_out - 1])
+ : $res[$value_out - 1];
+ $dates{$start} = $end;
+ }
+ my ($xmax, $ymax) = (500, 170);
+ &Chrono ("$IMG_dir/$filename", $title, $color_bg, $xmax, $ymax,
+ \%in, \%out, \%dates, $label_in, $label_out,
+ $color_in, $color_out, $unit);
+ $result .= "<IMG WIDTH=\"$xmax\" HEIGHT=\"$ymax\" ";
+ $result .= "SRC=\"$IMG_pth$filename\" ALT=\"Graph\">\n";
+ $i++;
+ }
+ $result .= "<P>\n";
+ }
+ $i = 0;
+ $result .= "<TABLE BORDER=\"1\"><TR>";
+ my $temp = '';
+ while (defined ${${$output{'index'}{'column'}}[$i]}{'title'}) {
+ my $title = &GetValue (${${$output{'index'}{'column'}}[$i]}{'title'});
+ my $name = '';
+ $name = &GetValue (${${$output{'index'}{'column'}}[$i]}{'name'})
+ if defined ${${$output{'index'}{'column'}}[$i]}{'name'};
+ my @list = split /\|/, $name;
+ if ($name) {
+ $result .= sprintf "<TH COLSPAN=%d>$title</TH>", $#list + 1;
+ }
+ else {
+ $result .= "<TH ROWSPAN=\"2\">$title</TH>";
+ }
+ foreach (@list) {
+ $temp .= "<TH>$_</TH>";
+ }
+ $i++;
+ }
+ $result .= "</TR>\n<TR>$temp</TR>\n";
+
+ $i = 0;
+ foreach (sort {$b cmp $a} (keys %data)) {
+ if ($CYCLE == 0 || $i < $CYCLE) {
+ my @list = split /\|/, $data{$_};
+ my $str = "<TR><TD ALIGN=LEFT>";
+ $str .= "<A HREF=\"$_\">" if -e "$rep/$_";
+ $str .= shift @list;
+ $str .= "</A>" if -e "$rep/$_";;
+ $str .= "</TD>";
+ while (@list) {
+ $str .= "<TD ALIGN=RIGHT>";
+ my $t = shift @list;
+ $t =~ s/^\0+//o; # remove garbage, if any.
+ $str .= "$t</TD>";
+ }
+ $str .= "</TR>\n";
+ $result .= "$str";
+ }
+ $i++;
+ }
+ $result .= "</TABLE>\n</CENTER>\n<P><HR>";
+ $result .= "innreport $version (c) 1996-1999 ";
+ $result .= "by Fabien Tassin <<A HREF=\"mailto:fta\@sofaraway.org\">";
+ $result .= "fta\@sofaraway.org</A>>.\n";
+ if (defined ($output{'default'}{'footer'})) {
+ my ($t) = $output{'default'}{'footer'} =~ m/^\"\s*(.*?)\s*\"$/o;
+ $t =~ s/\\\"/\"/go;
+ $result .= "<BR>" . $t;
+ }
+ $result .= "$HTML_footer\n</BODY>\n</HTML>\n";
+ my $name = $rep . "/" . $index;
+ while ($name =~ m/\/\.\.\//o) {
+ $name =~ s|^\./||o; # ^./xxx => ^xxx
+ $name =~ s|/\./|/|go; # xxx/./yyy => xxx/yyy
+ $name =~ s|/+|/|go; # xxx//yyy => xxx/yyy
+ $name =~ s|^/\.\./|/|o; # ^/../xxx => ^/xxx
+ $name =~ s|^[^/]+/\.\./||o; # ^xxx/../ => ^nothing
+ $name =~ s|/[^/]+/\.\./|/|go; # /yyy/../ => /
+ }
+
+ open (INDEX, "> $name") || die "Error: Unable to create $name\n";
+ print INDEX $result;
+ close INDEX;
+ 1;
+}
+
+sub Graph3d {
+ my $filename = shift; # filename
+ my $title = shift; # title
+ my $xmax = shift; # width
+ my $n = shift; # Number of hash code tables
+
+ no strict;
+ my ($i, $k, $t);
+ my @val;
+ for $i (0 .. $n - 1) {
+ push @val, shift; # hash code table
+ }
+ my $colors = shift; # colors table
+ my $labels = shift; # labels
+
+ my $max = 0;
+ my $max_size = 0;
+ my $size = 0;
+ foreach $k (sort keys (%{$val[0]})) {
+ $t = 0;
+ $size++;
+ for $i (0 .. $n - 1) {
+ $t += ${$val[$i]}{$k} if defined ${$val[$i]}{$k};
+ }
+ $max = $t if $max < $t;
+ $t = length "$k";
+ $max_size = $t if $max_size < $t;
+ }
+ $max = 1 unless $max;
+ $max_size *= gdSmallFont->width;
+
+ # relief
+ my ($rx, $ry) = (15, 5);
+
+ # margins
+ my ($mt, $mb) = (40, 40);
+ my $ml = $max_size > 30 ? $max_size + 8 : 30;
+
+ my $mr = 7 + (length "$max") * gdSmallFont->width;
+ $mr = 30 if $mr < 30;
+
+ # height of each bar
+ my $h = 12;
+
+ # difference between 2 bars
+ my $d = 25;
+
+ my $ymax = $size * $d + $mt + $mb;
+ my $image = new GD::Image ($xmax, $ymax);
+
+ my ($white, $black);
+ if (defined $output{'default'}{'graph_fg'}) {
+ my $t = $output{'default'}{'graph_fg'};
+ $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
+ $t =~ m/^[\da-fA-F]{6}$/o ||
+ die "Error in section 'default' section 'graph_fg'. Bad color.\n";
+ my @c = map { hex ($_) } ($t =~ m/^(..)(..)(..)$/);
+ $black = $image->colorAllocate (@c);
+ }
+ else {
+ $black = $image->colorAllocate ( 0, 0, 0);
+ }
+ if (defined $output{'default'}{'graph_bg'}) {
+ my $t = $output{'default'}{'graph_bg'};
+ $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
+ $t =~ m/^[\da-fA-F]{6}$/o ||
+ die "Error in section 'default' section 'graph_bg'. Bad color.\n";
+ my @c = map { hex ($_) } ($t =~ m/^(..)(..)(..)$/);
+ $white = $image->colorAllocate (@c);
+ }
+ else {
+ $white = $image->colorAllocate (255, 255, 255);
+ }
+ $image->filledRectangle (0, 0, $xmax, $ymax, $white);
+ my @col;
+ for $i (0 .. $n - 1) {
+ $col[$i][0] = $image->colorAllocate
+ ($$colors[$i][0], $$colors[$i][1], $$colors[$i][2]);
+ $col[$i][1] = $image->colorAllocate
+ ($$colors[$i][0] * 3 / 4, $$colors[$i][1] * 3 / 4,
+ $$colors[$i][2] * 3 / 4);
+ $col[$i][2] = $image->colorAllocate
+ ($$colors[$i][0] * 2 / 3, $$colors[$i][1] * 2 / 3,
+ $$colors[$i][2] * 2 / 3);
+ }
+
+ $image->transparent ($white) if $transparent;
+
+ $image->rectangle (0, 0, $xmax - 1, $size * $d + $mt + $mb - 1, $black);
+ $image->line (0, $mt - 5, $xmax - 1, $mt - 5, $black);
+ for $i (0 .. $n - 1) {
+ $image->string (gdSmallFont, $i * $xmax / $n + $mt - 10 + $rx,
+ ($mt - gdSmallFont->height) / 2, "$$labels[$i]", $black);
+ $image->filledRectangle ($i * $xmax / $n + 10, 8 + $ry / 2,
+ $i * $xmax / $n + $mt - 10, $mt - 12, $col[$i][0]);
+ $image->rectangle ($i * $xmax / $n + 10, 8 + $ry / 2,
+ $i * $xmax / $n + $mt - 10, $mt - 12, $black);
+ {
+ my $poly = new GD::Polygon;
+ $poly->addPt($i * $xmax / $n + 10, 8 + $ry / 2);
+ $poly->addPt($i * $xmax / $n + 10 + $rx / 2, 8);
+ $poly->addPt($i * $xmax / $n + $mt - 10 + $rx / 2, 8);
+ $poly->addPt($i * $xmax / $n + $mt - 10, 8 + $ry / 2);
+
+ $image->filledPolygon($poly, $col[$i][1]);
+ $image->polygon($poly, $black);
+ }
+ {
+ my $poly = new GD::Polygon;
+ $poly->addPt($i * $xmax / $n + $mt - 10 + $rx / 2, 8);
+ $poly->addPt($i * $xmax / $n + $mt - 10, 8 + $ry / 2);
+ $poly->addPt($i * $xmax / $n + $mt - 10, $mt - 12);
+ $poly->addPt($i * $xmax / $n + $mt - 10 + $rx / 2, $mt - 12 - $ry / 2);
+
+ $image->filledPolygon($poly, $col[$i][2]);
+ $image->polygon($poly, $black);
+ }
+ }
+ # Title
+ $image->string (gdMediumBoldFont, ($xmax - gdMediumBoldFont->width *
+ (length "$title")) / 2, $ymax - gdMediumBoldFont->height - 7,
+ "$title", $black);
+
+ my $e = $mt - $h + $d;
+ my $r = ($xmax - $ml - $mr - $rx) / $max;
+
+ # Axe Oz
+ $image->line ($ml + $rx, $mt, $ml + $rx, $size * $d + $mt - $ry, $black);
+ $image->line ($ml + $rx + $max * $r, $mt, $ml + $rx + $max * $r,
+ $size * $d + $mt - $ry, $black);
+ $image->line ($ml, $mt + $ry, $ml, $size * $d + $mt, $black);
+ # Axe Ox
+ $image->line ($ml + $rx, $size * $d + $mt - $ry,
+ $ml + $rx - 2 * $rx, $size * $d + $mt + $ry, $black);
+ # Axe Oy
+ $image->line ($ml + $rx, $size * $d + $mt - $ry,
+ $xmax - $mr / 2, $size * $d + $mt - $ry, $black);
+ $image->line ($ml, $size * $d + $mt,
+ $xmax - $mr - $rx, $size * $d + $mt, $black);
+
+ # Graduations..
+ my $nn = 10;
+ for $k (1 .. ($nn - 1)) {
+ $image->dashedLine ($ml + $rx + $k * ($xmax - $ml - $mr - $rx) / $nn,
+ $mt + 10, $ml + $rx + $k * ($xmax - $ml - $mr - $rx) / $nn,
+ $size * $d + $mt - $ry, $black);
+ $image->dashedLine ($ml + $rx + $k * ($xmax - $ml - $mr - $rx) / $nn,
+ $size * $d + $mt - $ry,
+ $ml + $k * ($xmax - $ml - $mr - $rx) / $nn,
+ $size * $d + $mt, $black);
+ $image->line ($ml + $k * ($xmax - $ml - $mr - $rx) / $nn,
+ $size * $d + $mt,
+ $ml + $k * ($xmax - $ml - $mr - $rx) / $nn,
+ $size * $d + $mt + 5, $black);
+ my $t = sprintf "%d%%", $k * 10;
+ $image->string (gdSmallFont, $ml + $k * ($xmax - $ml - $mr - $rx) / $nn -
+ (length "$t") * gdSmallFont->width / 2,
+ $size * $d + $mt + 6, "$t", $black);
+ }
+ {
+ my $t = sprintf "%d%%", 0;
+ $image->line ($ml, $size * $d + $mt, $ml, $size * $d + $mt + 5, $black);
+ $image->string (gdSmallFont, $ml - (length "$t") * gdSmallFont->width / 2,
+ $size * $d + $mt + 6, "$t", $black);
+ $image->line ($xmax - $mr, $size * $d + $mt - $ry,
+ $xmax - $mr - $rx, $size * $d + $mt, $black);
+ $image->line ($xmax - $mr - $rx, $size * $d + $mt,
+ $xmax - $mr - $rx, $size * $d + $mt + 5, $black);
+ $t = sprintf "%d%%", 100;
+ $image->string (gdSmallFont, $xmax - $mr - $rx
+ - (length "$t") * gdSmallFont->width / 2,
+ $size * $d + $mt + 6, "$t", $black);
+ }
+ foreach $k (sort {${$val[0]}{$b} <=> ${$val[0]}{$a}} keys (%{$val[0]})) {
+ $image->string (gdSmallFont, $ml - (length "$k") * gdSmallFont->width - 3,
+ $e + $h / 2 - gdSmallFont->height / 2, "$k", $black);
+ my $t = 0;
+ $image->line ($ml + ($t + ${$val[0]}{$k}) * $r + $rx - $rx, $e + $h,
+ $ml + ($t + ${$val[0]}{$k}) * $r + $rx, $e - $ry + $h,
+ $black);
+ for $i (0 .. $n - 1) {
+ next unless defined ${$val[$i]}{$k};
+ {
+ my $poly = new GD::Polygon;
+ $poly->addPt($ml + $t * $r, $e);
+ $poly->addPt($ml + $t * $r + $rx, $e - $ry);
+ $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r + $rx, $e - $ry);
+ $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r, $e);
+
+ $image->filledPolygon($poly, $col[$i][1]);
+ $image->polygon($poly, $black);
+ }
+ unless (${$val[$i + 1]}{$k} || ${$val[$i]}{$k} == 0) {
+ my $poly = new GD::Polygon;
+ $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r + $rx, $e - $ry);
+ $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r + $rx - $rx, $e);
+ $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r + $rx - $rx, $e + $h);
+ $poly->addPt($ml + ($t + ${$val[$i]}{$k}) * $r + $rx, $e - $ry + $h);
+
+ $image->filledPolygon($poly, $col[$i][2]);
+ $image->polygon($poly, $black);
+ }
+ $image->filledRectangle ($ml + $t * $r, $e,
+ $ml + ($t + ${$val[$i]}{$k}) * $r, $e + $h,
+ $col[$i][0]);
+ $image->rectangle ($ml + $t * $r, $e, $ml + ($t + ${$val[$i]}{$k}) * $r,
+ $e + $h, $black);
+ $t += ${$val[$i]}{$k};
+ }
+ # total length (offered)
+ $image->filledRectangle ($ml + $t * $r + $rx + 3,
+ $e - 2 - gdSmallFont->height / 2,
+ $ml + $t * $r + $rx + 4 +
+ gdSmallFont->width * length $t,
+ $e - 6 + gdSmallFont->height / 2, $white);
+ $image->string (gdSmallFont, $ml + $t * $r + $rx + 5,
+ $e - 3 - gdSmallFont->height / 2, "$t", $black);
+ # first value (accepted)
+ $image->filledRectangle ($ml + $t * $r + $rx + 3,
+ $e - 4 + gdSmallFont->height / 2,
+ $ml + $t * $r + $rx + 4 +
+ gdSmallFont->width * length "${$val[0]}{$k}",
+ $e - 2 + gdSmallFont->height, $white);
+ $image->string (gdSmallFont, $ml + $t * $r + $rx + 5,
+ $e - 5 + gdSmallFont->height / 2, ${$val[0]}{$k}, $black);
+ $e += $d;
+ }
+ open (IMG, "> $filename") || die "Error: Can't open \"$filename\": $!\n";
+ if ($GD_FORMAT eq 'png') {
+ print IMG $image->png;
+ }
+ else {
+ print IMG $image->gif;
+ }
+ close IMG;
+ $ymax;
+}
+
+sub Histo {
+ my ($filename, $title, $xmax, $factor,
+ $labelx, $labely, $val1, $labels1) = @_;
+
+ no strict;
+ my $max = 0;
+ my $ymax = 300;
+ my $nb = 0;
+ # A hugly hack to convert hashes to lists..
+ # and to adjust the first and the last value...
+ # this function should be rewritten..
+ my (@a, @b, $kk);
+ foreach $kk (sort keys (%$val1)) {
+ if (defined $$val1{$kk}) {
+ $nb++;
+ # Arg... the following MUST be removed !!!!!!!!!
+ $$val1{$kk} = $$val1{$kk} / $innreport_inn::inn_flow_time{$kk} * 3600
+ if ($innreport_inn::inn_flow_time{$kk} != 3600) &&
+ ($innreport_inn::inn_flow_time{$kk} != 0);
+ push @a, $$val1{$kk};
+ $max = $$val1{$kk} if $$val1{$kk} > $max;
+ push @b, $$labels1{$kk};
+ }
+ }
+ return 0 unless $nb; # strange, no data.
+ my $val = \@a;
+ my $labels = \@b;
+ my ($i, $j);
+ my ($marginl, $marginr, $margint, $marginb, $shx, $shy);
+
+ my $image = new GD::Image($xmax, $ymax);
+ my ($white, $black);
+ if (defined $output{'default'}{'graph_fg'}) {
+ my $t = $output{'default'}{'graph_fg'};
+ $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
+ $t =~ m/^[\da-fA-F]{6}$/o ||
+ die "Error in section 'default' section 'graph_fg'. Bad color.\n";
+ my @c = map { hex ($_) } ($t =~ m/^(..)(..)(..)$/);
+ $black = $image->colorAllocate (@c);
+ }
+ else {
+ $black = $image->colorAllocate ( 0, 0, 0);
+ }
+ if (defined $output{'default'}{'graph_bg'}) {
+ my $t = $output{'default'}{'graph_bg'};
+ $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
+ $t =~ m/^[\da-fA-F]{6}$/o ||
+ die "Error in section 'default' section 'graph_bg'. Bad color.\n";
+ my @c = map { hex $_ } ($t =~ m/^(..)(..)(..)$/);
+ $white = $image->colorAllocate (@c);
+ }
+ else {
+ $white = $image->colorAllocate (255, 255, 255);
+ }
+ $image->filledRectangle (0, 0, $xmax, $ymax, $white);
+ my $gray = $image->colorAllocate (128, 128, 128);
+ my $red = $image->colorAllocate (255, 0, 0);
+ my $red2 = $image->colorAllocate (189, 0, 0);
+ my $red3 = $image->colorAllocate (127, 0, 0);
+ my $coltxt = $black;
+
+ $image->transparent ($white) if $transparent;
+
+ my $FontWidth = gdSmallFont->width;
+ my $FontHeight = gdSmallFont->height;
+
+ $marginl = 60;
+ $marginr = 30;
+ $margint = 60;
+ $marginb = 30;
+ $shx = 7;
+ $shy = 7;
+
+ $max = 1 unless $max;
+ my $part = 8;
+ $max /= $factor;
+
+ my $old_max = $max;
+ {
+ my $t = log ($max) / log 10;
+ $t = sprintf "%.0f", $t - 1;
+ $t = exp ($t * log 10);
+ $max = sprintf "%.0f", $max / $t * 10 + 0.4;
+ my $t2 = sprintf "%.0f", $max / $part;
+ unless ($part * $t2 == $max) {
+ while ($part * $t2 != $max) {
+ $max++;
+ $t2 = sprintf "%d", $max / $part;
+ }
+ }
+ $max = $max * $t / 10;
+ }
+
+ # Title
+ $image->string (gdMediumBoldFont,
+ ($xmax - length ($title) * gdMediumBoldFont->width) / 2,
+ ($margint - $shy - gdMediumBoldFont->height) / 2,
+ $title, $coltxt);
+
+ # Labels
+ $image->string (gdSmallFont, $marginl / 2, $margint / 2, $labely, $coltxt);
+ $image->string (gdSmallFont, $xmax - $marginr / 2 -
+ $FontWidth * length ($labelx), $ymax - $marginb / 2,
+ $labelx, $coltxt);
+
+ # Max
+ $image->line ($marginl, $ymax - $marginb - $shy -
+ $old_max * ($ymax - $marginb - $margint - $shy) / $max,
+ $xmax - $marginr, $ymax - $marginb - $shy -
+ $old_max * ($ymax - $marginb - $margint - $shy) / $max, $red);
+ $image->line ($marginl, $ymax - $marginb - $shy -
+ $old_max * ($ymax - $marginb - $margint - $shy) / $max,
+ $marginl - $shx, $ymax - $marginb -
+ $old_max * ($ymax - $marginb - $margint - $shy) / $max, $red);
+
+ # Left
+ $image->line ($marginl - $shx, $margint + $shy,
+ $marginl - $shx, $ymax - $marginb, $coltxt);
+ $image->line ($marginl, $margint,
+ $marginl, $ymax - $marginb - $shy, $coltxt);
+ $image->line ($marginl, $margint,
+ $marginl - $shx, $margint + $shy, $coltxt);
+ $image->line ($marginl - $shx, $ymax - $marginb,
+ $marginl, $ymax - $marginb - $shy, $coltxt);
+
+ # Right
+ $image->line ($xmax - $marginr, $margint,
+ $xmax - $marginr, $ymax - $marginb - $shy, $coltxt);
+ $image->line ($xmax - $marginr - $shx, $ymax - $marginb,
+ $xmax - $marginr, $ymax - $marginb - $shy, $coltxt);
+
+ # Bottom
+ $image->line ($marginl - $shx, $ymax - $marginb,
+ $xmax - $marginr - $shx, $ymax - $marginb, $coltxt);
+ $image->line ($marginl, $ymax - $marginb - $shy,
+ $xmax - $marginr, $ymax - $marginb - $shy, $coltxt);
+ $image->fill ($xmax / 2, $ymax - $marginb - $shy / 2, $gray);
+
+ # Top
+ $image->line ($marginl, $margint,
+ $xmax - $marginr, $margint, $coltxt);
+ $image->setStyle ($coltxt, $coltxt, &GD::gdTransparent,
+ &GD::gdTransparent, &GD::gdTransparent);
+ # Graduations
+ for ($i = 0; $i <= $part; $i++) {
+ $j = $max * $i / $part ; # Warning to floor
+ # $j = ($max / $part) * ($i / 10000);
+ # $j *= 10000;
+
+ # Little hack...
+ $j = sprintf "%d", $j if $j > 100;
+
+ $image->line ($marginl - $shx - 3, $ymax - $marginb -
+ $i * ($ymax - $marginb - $margint - $shy) / $part,
+ $marginl - $shx, $ymax - $marginb -
+ $i * ($ymax - $marginb - $margint - $shy) / $part, $coltxt);
+ $image->line ($marginl - $shx, $ymax - $marginb -
+ $i * ($ymax - $marginb - $margint - $shy) / $part,
+ $marginl, $ymax - $marginb - $shy -
+ $i * ($ymax - $marginb - $margint - $shy) / $part, gdStyled);
+ $image->line ($marginl, $ymax - $marginb - $shy -
+ $i * ($ymax - $marginb - $margint - $shy) / $part,
+ $xmax - $marginr, $ymax - $marginb - $shy -
+ $i * ($ymax - $marginb - $margint - $shy) / $part, gdStyled);
+ $image->string (gdSmallFont,
+ $marginl - $shx - $FontWidth * length ("$j") - 7,
+ $ymax - $marginb -
+ ($i) * ($ymax - $marginb - $margint - $shy) / ($part) -
+ $FontHeight / 2, "$j", $coltxt);
+ }
+
+ # Graduation (right bottom corner)
+ $image->line ($xmax - $marginr - $shx, $ymax - $marginb,
+ $xmax - $marginr - $shx, $ymax - $marginb + 3, $coltxt);
+ # Bars
+ $i = 0;
+ my $w = ($xmax - $marginl - $marginr) / $nb;
+ my $k = $w / 5;
+ $$val[$nb - 1] = 0 unless $$val[$nb - 1];
+ foreach $j (@$val) {
+ my $MAX = 1;
+ if ($i++ <= $nb) {
+ # Graduation
+ $image->line ($marginl + ($i - 1) * $w - $shx, $ymax - $marginb,
+ $marginl + ($i - 1) * $w - $shx, $ymax - $marginb + 3,
+ $coltxt);
+ my $ii = sprintf "%d", $i / $MAX;
+ $image->string (gdSmallFont,
+ $marginl + ($i - 0.5) * $w + 1 -
+ ($FontWidth * length ($$labels[$i-1])) / 2 - $shx,
+ $ymax - $marginb + 3, $$labels[$i-1], $coltxt)
+ unless ($w < $FontWidth * length ($$labels[$i-1]))
+ && ($i != $MAX * $ii);
+
+ # Right
+ my $poly = new GD::Polygon;
+ $poly->addPt($marginl + ($i) * $w - $k, $ymax - $marginb - $shy -
+ $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
+ $poly->addPt($marginl + ($i) * $w - $k, $ymax - $marginb - $shy);
+ $poly->addPt($marginl + ($i) * $w - $k - $shx, $ymax - $marginb);
+ $poly->addPt($marginl + ($i) * $w - $k - $shx, $ymax - $marginb -
+ $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
+
+ $image->filledPolygon($poly, $red3);
+ $image->polygon($poly, $coltxt);
+
+ # Front
+ $image->filledRectangle ($marginl + ($i - 1) * $w + $k - $shx,
+ $ymax - $marginb -
+ $j / $factor * ($ymax - $marginb - $margint - $shy) / $max,
+ $marginl + ($i) * $w - $k - $shx,
+ $ymax - $marginb, $red);
+ $image->rectangle ($marginl + ($i - 1) * $w + $k - $shx,
+ $ymax - $marginb -
+ $j / $factor * ($ymax - $marginb - $margint - $shy) / $max,
+ $marginl + ($i) * $w - $k - $shx,
+ $ymax - $marginb, $coltxt);
+ # Top
+ my $poly2 = new GD::Polygon;
+ $poly2->addPt($marginl + ($i - 1) * $w + $k, $ymax - $marginb - $shy -
+ $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
+ $poly2->addPt($marginl + ($i) * $w - $k, $ymax - $marginb - $shy -
+ $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
+ $poly2->addPt($marginl + ($i) * $w - $k - $shx, $ymax - $marginb -
+ $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
+ $poly2->addPt($marginl + ($i - 1) * $w + $k - $shx, $ymax - $marginb -
+ $j / $factor * ($ymax - $marginb - $margint - $shy) / $max);
+
+ $image->rectangle (0, 0, $xmax - 1, $ymax - 1, $coltxt);
+ $image->filledPolygon($poly2, $red2);
+ $image->polygon($poly2, $coltxt);
+ }
+ }
+
+ open (IMG, "> $filename") || die "Can't create '$filename'\n";
+ if ($GD_FORMAT eq 'png') {
+ print IMG $image->png;
+ }
+ else {
+ print IMG $image->gif;
+ }
+ close IMG;
+ 1;
+}
+
+sub Chrono {
+ my $filename = shift; # filename
+ my $title = shift; # title
+ my $color_bg = shift; # background color
+ my $xmax = shift; # width
+ my $ymax = shift; # height
+
+ my $in = shift;
+ my $out = shift;
+ my $dates = shift;
+
+ my $legend_in = shift;
+ my $legend_out = shift;
+
+ my $color_in = shift;
+ my $color_out = shift;
+
+ my $unit = shift;
+
+ my $key;
+ my $x_min = 1E30;
+ my $x_max = 0;
+ my $y_min = 0;
+ my $y_max;
+ my $y_max_in = 0;
+ my $y_max_out = 0;
+
+ foreach $key (sort keys %$dates) {
+ $x_min = $key if $x_min > $key;
+ $x_max = $$dates{$key} if $x_max < $$dates{$key};
+ my $t = $$out{$key} / ($$dates{$key} - $key);
+ $y_max_out = $t if $y_max_out < $t;
+ $t = $$in{$key} / ($$dates{$key} - $key);
+ $y_max_in = $t if $y_max_in < $t;
+ }
+ $y_max = $y_max_out > $y_max_in ? $y_max_out : $y_max_in;
+ my $factor = 1;
+ if ($y_max < 1) {
+ $factor = 60;
+ if ($y_max < 4 / 60) {
+ $y_max = 4 / 60;
+ }
+ else {
+ $y_max = int ($y_max * $factor) + 1;
+ $y_max += (4 - ($y_max % 4)) % 4;
+ $y_max /= $factor;
+ }
+ }
+ else {
+ $y_max = int ($y_max) + 1;
+ $y_max += (4 - ($y_max % 4)) % 4;
+ }
+
+ $unit .= "/" . ($factor == 60 ? "min" : "sec");
+
+ # min range is 4 weeks.
+ my $delta = $x_max - $x_min;
+ $x_min = $x_max - 3024000 if $delta < 3024000;
+ # between 4 weeks and one year, range is a year.
+ $x_min = $x_max - 31536000 if ($delta < 31536000 && $delta > 3024000);
+ # max range is 13 months
+ $x_min = $x_max - 34128000 if $delta > 34128000;
+ my $image = new GD::Image ($xmax, $ymax);
+ my ($white, $black);
+ if (defined $output{'default'}{'graph_fg'}) {
+ my $t = $output{'default'}{'graph_fg'};
+ $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
+ $t =~ m/^[\da-fA-F]{6}$/o ||
+ die "Error in section 'default' section 'graph_fg'. Bad color.\n";
+ my @c = map { hex $_ } ($t =~ m/^(..)(..)(..)$/);
+ $black = $image->colorAllocate (@c);
+ }
+ else {
+ $black = $image->colorAllocate ( 0, 0, 0);
+ }
+ if (defined $output{'default'}{'graph_bg'}) {
+ my $t = $output{'default'}{'graph_bg'};
+ $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
+ $t =~ m/^[\da-fA-F]{6}$/o ||
+ die "Error in section 'default' section 'graph_bg'. Bad color.\n";
+ my @c = map { hex $_ } ($t =~ m/^(..)(..)(..)$/);
+ $white = $image->colorAllocate (@c);
+ }
+ else {
+ $white = $image->colorAllocate (255, 255, 255);
+ }
+ my $bg;
+ if (defined $color_bg) {
+ $color_bg =~ m/^\#[\da-fA-F]{6}$/o ||
+ die "Error in section 'index'. Bad color $color_bg.\n";
+ my @c = map { hex $_ } ($color_bg =~ m/^\#(..)(..)(..)$/);
+ $bg = $image->colorAllocate (@c);
+ }
+ else {
+ $bg = $image->colorAllocate (255, 255, 206);
+ }
+ my $col_in;
+ if (defined $color_in) {
+ $color_in =~ m/^\#[\da-fA-F]{6}$/o ||
+ die "Error in section 'index'. Bad color $color_in.\n";
+ my @c = map { hex $_ } ($color_in =~ m/^\#(..)(..)(..)$/);
+ $col_in = $image->colorAllocate (@c);
+ }
+ else {
+ $col_in = $image->colorAllocate ( 80, 159, 207);
+ }
+ my $col_out;
+ my @col_out = ( 0, 0, 255);
+ if (defined $color_out) {
+ $color_out =~ m/^\#[\da-fA-F]{6}$/o ||
+ die "Error in section 'index'. Bad color $color_out.\n";
+ my @c = map { hex $_ } ($color_out =~ m/^\#(..)(..)(..)$/);
+ $col_out = $image->colorAllocate (@c);
+ @col_out = @c;
+ }
+ else {
+ $col_out = $image->colorAllocate (@col_out);
+ }
+
+ my $white2 = $image->colorAllocate (255, 255, 255);
+ my $gray = $image->colorAllocate (192, 192, 192);
+ my $red = $image->colorAllocate (255, 0, 0);
+ my $coltxt = $black;
+
+ my $size = 22; # legend
+ # legend statistics
+ my ($max_in, $max_out) = (0, 0); # min
+ my ($min_in, $min_out) = (1E10, 1E10); # max
+ my ($t_in, $t_out) = (0, 0); # time
+ my ($s_in, $s_out) = (0, 0); # sum
+
+ $image->filledRectangle (0, 0, $xmax, $ymax, $gray);
+ $image->transparent ($gray) if $transparent;
+
+ my $FontWidth = gdSmallFont->width;
+ my $FontHeight = gdSmallFont->height;
+ $image->setStyle ($black, &GD::gdTransparent, &GD::gdTransparent);
+
+ my $marginl = 13 + $FontWidth * length (sprintf "%d", $y_max * $factor);
+ my $marginr = 15 + 4 * $FontWidth; # "100%"
+ my $margint = 2 * $FontHeight + gdMediumBoldFont->height;
+ my $marginb = 2 * $FontHeight + $size;
+ my $xratio = ($xmax - $marginl - $marginr) / ($x_max - $x_min);
+ my $yratio = ($ymax - $margint - $marginb) / ($y_max - $y_min);
+
+ my $frame = new GD::Polygon;
+ $frame->addPt(2, $margint - $FontHeight -3);
+ $frame->addPt($xmax - 2, $margint - $FontHeight -3);
+ $frame->addPt($xmax - 2, $ymax - 3);
+ $frame->addPt(2, $ymax - 3);
+ $image->filledPolygon($frame, $white2);
+ $image->polygon($frame, $black);
+
+ $image->filledRectangle ($marginl, $margint,
+ $xmax - $marginr, $ymax - $marginb, $bg);
+ my $brush = new GD::Image(1, 2);
+ my $b_col = $brush->colorAllocate(@col_out);
+ $brush->line(0, 0, 0, 1, $b_col);
+ $image->setBrush($brush);
+ my ($old_x, $old_y_in, $old_y_out);
+ foreach $key (sort keys %$dates) {
+ next if $key < $x_min;
+ my $delta = $$dates{$key} - $key;
+ $min_in = $$in{$key} / $delta if $min_in > $$in{$key} / $delta;
+ $max_in = $$in{$key} / $delta if $max_in < $$in{$key} / $delta;
+ $min_out = $$out{$key} / $delta if $min_out > $$out{$key} / $delta;
+ $max_out = $$out{$key} / $delta if $max_out < $$out{$key} / $delta;
+ $t_in += $delta;
+ $s_in += $$in{$key};
+ $s_out += $$out{$key};
+
+ my $tt_in = $$in{$key} / ($$dates{$key} - $key) * $yratio;
+ my $tt_out = $$out{$key} / ($$dates{$key} - $key) * $yratio;
+ my $new_x = $marginl + ($key - $x_min) * $xratio;
+ $image->filledRectangle ($marginl + ($key - $x_min) * $xratio,
+ $ymax - $marginb - $tt_in,
+ $marginl + ($$dates{$key} - $x_min) * $xratio,
+ $ymax - $marginb, $col_in);
+ if (defined $old_x) {
+ $old_x = $new_x if $old_x > $new_x;
+ my $poly = new GD::Polygon;
+ $poly->addPt($old_x, $old_y_in);
+ $poly->addPt($new_x, $ymax - $marginb - $tt_in);
+ $poly->addPt($new_x, $ymax - $marginb);
+ $poly->addPt($old_x, $ymax - $marginb);
+ $image->filledPolygon($poly, $col_in);
+ }
+ $image->line ($marginl + ($key - $x_min) * $xratio,
+ $ymax - $marginb - $tt_out,
+ $marginl + ($$dates{$key} - $x_min) * $xratio,
+ $ymax - $marginb - $tt_out, &GD::gdBrushed);
+ $image->line ($old_x, $old_y_out, $new_x,
+ $ymax - $marginb - $tt_out, $col_out) if defined $old_x;
+ $old_x = $marginl + ($$dates{$key} - $x_min) * $xratio;
+ $old_y_in = $ymax - $marginb - $tt_in;
+ $old_y_out = $ymax - $marginb - $tt_out;
+ }
+ $t_out = $t_in;
+
+ # main frame
+ $image->rectangle ($marginl, $margint,
+ $xmax - $marginr, $ymax - $marginb, $black);
+ # graduations
+ my $i;
+ foreach $i (0, 25, 50, 75, 100) {
+ my $t = $ymax - $margint - $marginb;
+ $image->line ($marginl, $ymax - $marginb - $i / 100 * $t,
+ $xmax - $marginr, $ymax - $marginb - $i / 100 * $t,
+ &GD::gdStyled);
+ $image->line ($xmax - $marginr, $ymax - $marginb - $i / 100 * $t,
+ $xmax - $marginr + 3, $ymax - $marginb - $i / 100 * $t,
+ $black);
+ $image->line ($marginl - 3, $ymax - $marginb - $i / 100 * $t,
+ $marginl, $ymax - $marginb - $i / 100 * $t,
+ $black);
+ $image->string (&GD::gdSmallFont, $xmax - $marginr + 8, - $FontHeight / 2 +
+ $ymax - $marginb - $i / 100 * $t, "$i%", $black);
+ my $s = sprintf "%d", $y_max * $i / 100 * $factor;
+ $image->string (&GD::gdSmallFont, $marginl - 5 - $FontWidth * length $s,
+ - $FontHeight / 2 +
+ $ymax - $marginb - $i / 100 * $t, $s, $black);
+ }
+ ##
+ my $w = 604800; # number of seconds in a week
+ my $y = 31536000; # number of seconds in a 365 days year
+ my $mm = 2592000; # number of seconds in a 30 days month
+ if ($x_max - $x_min <= 3024000) { # less than five weeks
+ # unit is a week
+ # 1/1/1990 is a monday. Use this as a basis.
+ my $d = 631152000; # number of seconds between 1/1/1970 and 1/1/1990
+ my $n = int ($x_min / $y);
+ my $t = $x_min - $n * $y - int (($n - 2) / 4) * 24 * 3600;
+ my $f = int ($t / $w);
+ $n = $d + int (($x_min - $d) / $w) * $w;
+ while ($n < $x_max) {
+ $t = $marginl + ($n - $x_min) * $xratio;
+ if ($n > $x_min) {
+ $image->line ($t, $margint, $t, $ymax - $marginb, &GD::gdStyled);
+ $image->line ($t, $ymax - $marginb, $t, $ymax - $marginb + 2, $black);
+ }
+ $image->string (&GD::gdSmallFont, $FontWidth * 7 / 2 + $t,
+ $ymax - $marginb + 4, (sprintf "Week %02d", $f), $black)
+ if ($n + $w / 2 > $x_min) && ($n + $w / 2 < $x_max);
+ $f++;
+ $n += $w;
+ $t = int ($n / $y);
+ $f = 0
+ if $n - $y * $t - int (($t - 2) / 4) * 24 * 3600 < $w && $f > 50;
+ }
+ $d = 86400; # 1 day
+ $n = int ($x_min / $y);
+ $t = $n * $y + int (($n - 2) / 4) * 24 * 3600;
+ $i = 0;
+ my $x;
+ while ($t < $x_max) {
+ $x = $marginl + ($t - $x_min) * $xratio;
+ $image->line ($x, $margint, $x, $ymax - $marginb + 2, $red)
+ if $t > $x_min;
+ $t += $mm;
+ $t += $d if $i == 0 || $i == 2 || $i == 4 ||
+ $i == 6 || $i == 7 || $i == 9 || $i == 11; # 31 days months
+ if ($i == 1) { # february ?
+ $t -= 2 * $d;
+ $t += $d unless (1970 + int ($t / $y)) % 4;
+ }
+ $i++;
+ $i = 0 if $i == 12; # Happy New Year !!
+ }
+ }
+ else {
+ # unit is a month
+ my $n = int ($x_min / $y);
+ my $t = $n * $y + int (($n - 2) / 4) * 24 * 3600;
+ my @m = ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
+ my $d = 86400; # 1 day
+ my $i = 0;
+ my $x;
+ while ($t < $x_max) {
+ $x = $marginl + ($t - $x_min) * $xratio;
+ if ($t > $x_min) {
+ $image->line ($x, $margint, $x, $ymax - $marginb, &GD::gdStyled);
+ $image->line ($x, $ymax - $marginb, $x,
+ $ymax - $marginb + 2, $black);
+ $image->line ($x, $margint, $x, $ymax - $marginb, $red) unless $i;
+ }
+ $image->string (&GD::gdSmallFont,
+ $mm * $xratio / 2 - $FontWidth * 3 / 2 +
+ $x, $ymax - $marginb + 4, (sprintf "%s", $m[$i]),
+ $black)
+ if ($t + 2 * $w > $x_min) && ($x_max > 2 * $w + $t);
+ $t += $mm;
+ $t += $d if ($i == 0 || $i == 2 || $i == 4 ||
+ $i == 6 || $i == 7 || $i == 9 || $i == 11); # 31 days months
+ if ($i == 1) { # february ?
+ $t -= 2 * $d;
+ $t += $d unless (1970 + int ($t / $y)) % 4;
+ }
+ $i++;
+ $i = 0 if $i == 12; # Happy New Year !!
+ }
+ }
+
+ # Add the little red arrow
+ my $poly = new GD::Polygon;
+ $poly->addPt($xmax - $marginr - 2, $ymax - $marginb - 3);
+ $poly->addPt($xmax - $marginr + 4, $ymax - $marginb);
+ $poly->addPt($xmax - $marginr - 2, $ymax - $marginb + 3);
+ $image->filledPolygon($poly, $red);
+
+ # Title
+ $image->string (&GD::gdMediumBoldFont,
+ $xmax / 2 - $FontWidth * length ($title) / 2, 4,
+ $title, $black);
+
+ # Legend
+ my $y_in = $ymax - $size - $FontHeight + 5;
+ $image->string (&GD::gdSmallFont, $marginl, $y_in, $legend_in, $col_in);
+ $image->string (&GD::gdSmallFont, $xmax / 4, $y_in,
+ (sprintf "Min: %5.1f $unit", $min_in * $factor), $black);
+ $image->string (&GD::gdSmallFont, $xmax / 2, $y_in,
+ (sprintf "Avg: %5.1f $unit", $s_in / $t_in * $factor), $black);
+ $image->string (&GD::gdSmallFont, 3 * $xmax / 4, $y_in,
+ (sprintf "Max: %5.1f $unit", $max_in * $factor), $black);
+
+ my $y_out = $ymax - $size + 5;
+ $image->string (&GD::gdSmallFont, $marginl, $y_out, $legend_out, $col_out);
+ $image->string (&GD::gdSmallFont, $xmax / 4, $y_out,
+ (sprintf "Min: %5.1f $unit", $min_out * $factor), $black);
+ $image->string (&GD::gdSmallFont, $xmax / 2, $y_out,
+ (sprintf "Avg: %5.1f $unit", $s_out / $t_out * $factor), $black);
+ $image->string (&GD::gdSmallFont, 3 * $xmax / 4, $y_out,
+ (sprintf "Max: %5.1f $unit", $max_out * $factor), $black);
+
+ open (IMG, "> $filename") || die "Error: Can't open \"$filename\": $!\n";
+ if ($GD_FORMAT eq 'png') {
+ print IMG $image->png;
+ }
+ else {
+ print IMG $image->gif;
+ }
+ close IMG;
+ return $ymax;
+}
+
+sub Write_all_results {
+ my $HTML_output = shift;
+ my $h = shift;
+ my $k;
+
+ my $title = $$h{'default'}{'title'} ?
+ $$h{'default'}{'title'} : "Daily Usenet report";
+ $title =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ $title =~ s/\\\"/\"/go;
+ my $Title = $title;
+ $Title =~ s/<.*?>//go;
+ {
+ my $Title = $Title;
+ $Title =~ s/\&/&/go;
+ $Title =~ s/\</</go;
+ $Title =~ s/\>/>/go;
+ print "$Title from $first_date to $last_date\n\n";
+ }
+
+ if ($HTML) {
+ my $body = defined $output{'default'}{'html_body'} ?
+ $output{'default'}{'html_body'} : '';
+ $body =~ s/^\"\s*(.*?)\s*\"$/ $1/o;
+ $body =~ s/\\\"/\"/go;
+ open (HTML, "> $HTML_output") || die "Error: cant open $HTML_output\n";
+
+ print HTML "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n" .
+ "<HTML>\n<HEAD>\n<TITLE>$Title: $first_date</TITLE>\n" .
+ "<!-- innreport $version -->\n</HEAD>\n<BODY $body>\n" .
+ "$HTML_header\n<CENTER><H1>$title</H1>\n" .
+ "<H3>$first_date -- $last_date</H3>\n</CENTER>\n<P><HR><P>\n";
+
+ # Index
+ print HTML "<UL>\n";
+ foreach $k (@{$$h{'_order_'}}) {
+ next if $k =~ m/^(default|index)$/;
+ my ($data) = $$h{$k}{'data'} =~ m/^\"\s*(.*?)\s*\"$/o;
+ $data =~ s/^\%/\%$CLASS\:\:/ unless $data eq '%prog_type';
+ my %data;
+ { local $^W = 0; no strict; %data = eval $data }
+ my ($string) = $$h{$k}{'title'} =~ m/^\"\s*(.*?)\s*\"$/o;
+ $string =~ s/\s*:$//o;
+ my $want = 1;
+
+ ($want) = $$h{$k}{'skip'} =~ m/^\"?\s*(.*?)\s*\"?$/o
+ if defined $$h{$k}{'skip'};
+ $want = $want eq 'true' ? 0 : 1;
+ print HTML "<LI><A HREF=\"#$k\">$string</A>\n" if %data && $want;
+ }
+ print HTML "</UL><P><HR><P>\n";
+ }
+ if (@unrecognize && $WANT_UNKNOWN) {
+ my $mm = $#unrecognize;
+ print HTML "<A NAME=\"unrecognize\">" if $HTML && $WANT_HTML_UNKNOWN;
+ print "Unknown entries from news log file:\n";
+ print HTML "<STRONG>Unknown entries from news log file:</STRONG></A><P>\n"
+ if $HTML && $WANT_HTML_UNKNOWN;
+ $mm = $MAX_UNRECOGNIZED - 1
+ if $MAX_UNRECOGNIZED > 0 && $mm > $MAX_UNRECOGNIZED - 1;
+ if ($mm < $unrecognize_max && $unrecognize_max > 0) {
+ printf HTML "First %d / $unrecognize_max lines (%3.1f%%)<BR>\n", $mm + 1,
+ ($mm + 1) / $unrecognize_max * 100 if $HTML && $WANT_HTML_UNKNOWN;
+ printf "First %d / $unrecognize_max lines (%3.1f%%)\n", $mm + 1,
+ ($mm + 1) / $unrecognize_max * 100;
+ }
+
+ my $l;
+ for $l (0 .. $mm) {
+ chomp $unrecognize[$l]; # sometimes, the last line need a CR
+ print "$unrecognize[$l]\n"; # so, we always add one
+ if ($HTML && $WANT_HTML_UNKNOWN) {
+ $unrecognize[$l] =~ s/&/\&/g;
+ $unrecognize[$l] =~ s/</\</g;
+ $unrecognize[$l] =~ s/>/\>/g;
+ print HTML "$unrecognize[$l]<BR>\n";
+ }
+ }
+ print "\n";
+ print HTML "<P><HR><P>\n" if $HTML && $WANT_HTML_UNKNOWN;
+ }
+
+ close HTML if $HTML;
+ foreach $k (@{$$h{'_order_'}}) {
+ next if $k =~ m/^(default|index)$/;
+ &Write_Results($HTML_output, $k, $h);
+ }
+ if ($HTML) {
+ open (HTML, ">> $HTML_output") || die "Error: cant open $HTML_output\n";
+ print HTML <<EOT;
+innreport $version (c) 1996-1999 by Fabien Tassin
+<<A HREF="mailto:fta\@sofaraway.org">fta\@sofaraway.org</A>>.
+EOT
+ if (defined $$h{'default'}{'footer'}) {
+ my ($t) = $$h{'default'}{'footer'} =~ m/^\"\s*(.*?)\s*\"$/o;
+ $t =~ s/\\\"/\"/go;
+ print HTML "<BR>" . $t;
+ }
+ print HTML "\n$HTML_footer";
+ printf HTML "\n<!-- Running time: %s -->", second2time(time - $start_time);
+ print HTML "\n</BODY>\n</HTML>\n";
+ close HTML;
+ }
+}
+
+sub Write_Results {
+ my $HTML_output = shift;
+ my $report = shift;
+ my $data = shift;
+ my %output = %$data;
+ return 0 unless defined $output{$report}; # no data to write
+ return 0 if defined $output{$report}{'skip'} &&
+ $output{$report}{'skip'} =~ m/^true$/io;
+ my ($TEXT, $HTML, $DOUBLE);
+
+ # Need a text report ?
+ $TEXT = defined $output{$report}{'text'} ? $output{$report}{'text'} :
+ (defined $output{'default'}{'text'} ? $output{'default'}{'text'} : '');
+ die "Error in config file. Field 'text' is mandatory.\n" unless $TEXT;
+ $TEXT = ($TEXT =~ m/^true$/io) ? 1 : 0;
+
+ # Need an html report ?
+ if ($HTML_output) {
+ $HTML = defined $output{$report}{'html'} ? $output{$report}{'html'} :
+ (defined $output{'default'}{'html'} ? $output{'default'}{'html'} : '');
+ die "Error in config file. Field 'html' is mandatory.\n" unless $HTML;
+ $HTML = ($HTML =~ m/^true$/io) ? 1 : 0;
+ }
+ # Double table ?
+ $DOUBLE = defined $output{$report}{'double'} ?
+ $output{$report}{'double'} : 0;
+ $DOUBLE = ($DOUBLE =~ m/^true$/io) ? 1 : 0;
+
+ # Want to truncate the report ?
+ my $TOP = defined $output{$report}{'top'} ? $output{$report}{'top'} : -1;
+ my $TOP_HTML = defined $output{$report}{'top_html'} ?
+ $output{$report}{'top_html'} : $TOP;
+ my $TOP_TEXT = defined $output{$report}{'top_text'} ?
+ $output{$report}{'top_text'} : $TOP;
+
+ my (%h, %d, $h);
+ {
+ my $t = $output{$report}{'data'} ||
+ die "Error in section $report. Need a 'data' field.\n";
+ $t =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ $t =~ s/^\%/\%$CLASS\:\:/ unless $t eq '%prog_type';
+ %d = eval $t;
+ return unless %d; # nothing to report. exit.
+ return unless keys (%d); # nothing to report. exit.
+ }
+ {
+ my $t = defined $output{$report}{'sort'} ? $output{$report}{'sort'} :
+ "\$a cmp \$b";
+ $t =~ s/\n/ /smog;
+ $t =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ $t =~ s/([\$\%\@])/$1${CLASS}\:\:/go;
+ $t =~ s/([\$\%\@])${CLASS}\:\:(prog_(?:size|type)|key|num)/$1$2/go;
+ $t =~ s/\{\$${CLASS}\:\:(a|b)\}/\{\$$1\}/go;
+ $t =~ s/\$${CLASS}\:\:(a|b)/\$$1/go;
+ $h = $t;
+ }
+
+ if ($HTML) {
+ open (HTML, ">> $HTML_output") || die "Error: cant open $HTML_output\n";
+ }
+ print "\n" if $TEXT;
+ my ($key, $key1, $key2);
+ if (defined $output{$report}{'title'}) {
+ my $t = $output{$report}{'title'};
+ $t =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ if ($HTML) {
+ print HTML "<A NAME=\"$report\">";
+ my $html = $t;
+ $html =~ s/(:?)$/ [Top $TOP_HTML]$1/o if $TOP_HTML > 0;
+ $html =~ s|^(.*)$|<STRONG>$1</STRONG>|;
+ print HTML "$html</A>\n<P>\n<CENTER>\n<TABLE BORDER=\"1\">\n";
+ }
+ $t =~ s/(:?)$/ [Top $TOP_TEXT]$1/o if $TOP_TEXT > 0;
+ print "$t\n" if $TEXT;
+ }
+ my $numbering = 0;
+ $numbering = 1 if defined $output{$report}{'numbering'} &&
+ $output{$report}{'numbering'} =~ m/^true$/o;
+ my $i;
+ my $s = '';
+ my $html = '';
+ my $first = 0;
+
+ foreach $i (@{$output{$report}{'column'}}) {
+ my ($v1, $v2);
+
+ my $wtext = defined $$i{'text'} ? $$i{'text'} : 1;
+ $wtext = $wtext =~ m/^(1|true)$/io ? 1 : 0;
+ my $whtml = defined $$i{'html'} ? $$i{'html'} : 1;
+ $whtml = $whtml =~ m/^(1|true)$/io ? 1 : 0;
+
+ $v1 = defined ($$i{'format_name'}) ? $$i{'format_name'} :
+ (defined ($$i{'format'}) ? $$i{'format'} : "%s");
+ $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ $v2 = $$i{'name'};
+ $v2 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ $s .= sprintf $v1 . " ", $v2 if $wtext && !($DOUBLE && $first == 1);
+ if ($HTML && $whtml) {
+ my $v1 = $v1;
+ $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?(\w)/\%$1/g;
+ my $temp = $first ? "CENTER" : "LEFT";
+ $temp .= "\" COLSPAN=\"2" if $numbering && !$first;
+ $html .= sprintf "<TH ALIGN=\"$temp\">$v1</TH>", $v2;
+ }
+ $first++;
+ }
+ $s =~ s/\s*$//;
+ print "$s\n" if $TEXT;
+ $s = '';
+ if ($HTML) {
+ print HTML "<TR>$html</TR>\n<TR><TD></TD></TR>\n";
+ $html = '';
+ }
+ my $num = 0;
+ my $done;
+ if ($DOUBLE) {
+ my $num_d = 0;
+ foreach $key1 (sort keys (%d)) {
+ $done = 0;
+ $num = 0;
+ $num_d++;
+ $s = '';
+ $html = '';
+ my @res;
+ foreach $key2 (sort {$d{$key1}{$b} <=> $d{$key1}{$a}}
+ keys (%{$d{$key1}})) {
+ my $first = 0;
+ $num++;
+ foreach $i (@{$output{$report}{'column'}}) {
+ my ($v1, $v2, $p);
+
+ my $wtext = defined $$i{'text'} ? $$i{'text'} : 1;
+ $wtext = $wtext =~ m/^(1|true)$/io ? 1 : 0;
+ my $whtml = defined $$i{'html'} ? $$i{'html'} : 1;
+ $whtml = $whtml =~ m/^(1|true)$/io ? 1 : 0;
+
+ # is it the primary key ?
+ $p = 0;
+ $p = 1 if defined $$i{'primary'} && $$i{'primary'} =~ m/true/;
+
+ # format
+ $v1 = defined ($$i{'format'}) ? $$i{'format'} : "%s";
+ $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+
+ # value
+ $v2 = $$i{'value'};
+ $v2 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ my $r ='';
+ if ($v2) {
+ $r = &EvalExpr ($v2, $key2, $num, $key1);
+ die "Error in section $report column $$i{'name'}. " .
+ "Invalid 'value' value.\n" unless defined $r;
+ }
+ $res[$first] += $r if $v1 =~ m/\%-?(?:\d+(?:\.\d+)?)?d/o;
+ if ($p) {
+ $s .= sprintf $v1. "\n", $r unless $done || !$wtext;
+ if ($HTML && $whtml) {
+ if ($done) {
+ $html .= "<TD></TD>";
+ }
+ else {
+ $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
+ $html .= $numbering ? "<TH ALIGN=\"CENTER\">$num_d</TH>" : '';
+ # unless $first;
+ $html .= sprintf "<TD ALIGN=\"LEFT\">$v1</TD></TR>\n", $r;
+ $html .= "<TR><TD></TD>";
+ }
+ }
+ }
+ else {
+ if ($wtext) {
+ $s .= " " if $first == 1;
+ $s .= sprintf $v1 . " ", $r;
+ }
+ if ($HTML && $whtml) {
+ $html .= $numbering ? "<TD></TD>" : '' if $first == 1;
+ $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
+ my $temp = $first > 1 ? "RIGHT" : "LEFT";
+ $html .= sprintf "<TD ALIGN=\"$temp\">$v1</TD>", $r;
+ }
+ }
+ $done = 1 if $p;
+ $first++;
+ }
+ $s =~ s/\s*$//;
+ $s =~ s/\\n/\n/g;
+ print "$s\n" if $TEXT && ($num <= $TOP_TEXT || $TOP_TEXT == -1);
+ if ($HTML && ($num <= $TOP_HTML || $TOP_HTML == -1)) {
+ $html =~ s/\\n//g;
+ print HTML "<TR>$html</TR>\n";
+ }
+ $s = '';
+ $html = '';
+ }
+ $first = 0;
+ $s = '';
+ $html = '';
+ if ($TOP_TEXT != -1 && $TOP_HTML != -1) {
+ foreach $i (@{$output{$report}{'column'}}) {
+ if (defined $$i{'primary'} && $$i{'primary'} =~ m/true/o) {
+ $first++;
+ $s .= ' ';
+ $html .= "<TD></TD>" if $HTML;
+ $html .= "<TD></TD>" if $HTML && $numbering;
+ next;
+ }
+ my ($v1, $v2);
+ $v1 = defined ($$i{'format_total'}) ? $$i{'format_total'} :
+ (defined ($$i{'format'}) ? $$i{'format'} : "%s");
+ $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ my $r = $first == 1 ? $num : $res[$first];
+ $s .= sprintf $v1 . " ", $r;
+ if ($HTML) {
+ my $temp = $first > 1 ? "RIGHT" : "LEFT";
+ $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
+ $v1 =~ s|(.*)|<STRONG>$1</STRONG>|o unless $first > 1;
+ $html .= sprintf "<TD ALIGN=\"$temp\">$v1</TD>", $r;
+ }
+ $first++;
+ }
+ $s =~ s/\s*$//;
+ $s =~ s/\\n//g;
+ print "$s\n" if $TEXT;
+ print HTML "<TR>$html</TR>\n" if $HTML;
+ }
+ }
+ print "\n" if $TEXT;
+ print HTML "<TR><TD></TD></TR>\n" if $HTML;
+ $first = 0;
+ $num = $num_d;
+ $s = '';
+ $html = '';
+ foreach $i (@{$output{$report}{'column'}}) {
+ my $wtext = defined $$i{'text'} ? $$i{'text'} : 1;
+ $wtext = $wtext =~ m/^(1|true)$/io ? 1 : 0;
+ my $whtml = defined $$i{'html'} ? $$i{'html'} : 1;
+ $whtml = $whtml =~ m/^(1|true)$/io ? 1 : 0;
+
+ my ($v1, $v2);
+ $v1 = defined $$i{'format_total'} ? $$i{'format_total'} :
+ (defined $$i{'format'} ? $$i{'format'} : "%s");
+ $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ $v2 = $$i{'total'} ||
+ die "Error in section $report column $$i{'name'}. " .
+ "Need a 'total' field.\n";
+ $v2 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ my $r = '';
+ if ($v2) {
+ $r = &EvalExpr ($v2, $key2, $num, 1);
+ die "Error in section $report column $$i{'name'}. " .
+ "Invalid 'total' value.\n" unless defined $r;
+ }
+ $s .= sprintf $v1 . " ", $r if $wtext && $first != 1;
+ if ($HTML && $whtml) {
+ my $temp = $first ? "RIGHT" : "LEFT";
+ $temp .= "\" COLSPAN=\"2" if $numbering && !$first;
+ $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
+ $v1 =~ s|(.*)|<STRONG>$1</STRONG>|o unless $first;
+ $html .= $first == 1 ? "<TD></TD>" :
+ sprintf "<TD ALIGN=\"$temp\">$v1</TD>", $r;
+ }
+ $first++;
+ }
+ $s =~ s/\s*$//;
+ $s =~ s/\\n//g;
+ print "$s\n" if $TEXT;
+ print HTML "<TR>$html</TR>\n</TABLE>\n</CENTER>\n<P>\n<HR>\n" if $HTML;
+ }
+ else {
+ # foreach $key (sort { local $^W = 0; no strict; eval $h } (keys (%d)))
+ foreach $key ((eval "sort {local \$^W = 0; no strict; $h} (keys (%d))")) {
+ next unless defined $key;
+ next unless defined $d{$key}; # to avoid problems after some undef()
+ $num++;
+ next unless $num <= $TOP_HTML || $TOP_HTML == -1 ||
+ $num <= $TOP_TEXT || $TOP_TEXT == -1;
+ my $first = 0;
+ foreach $i (@{$output{$report}{'column'}}) {
+ my $wtext = defined $$i{'text'} ? $$i{'text'} : 1;
+ $wtext = $wtext =~ m/^(1|true)$/io ? 1 : 0;
+ my $whtml = defined $$i{'html'} ? $$i{'html'} : 1;
+ $whtml = $whtml =~ m/^(1|true)$/io ? 1 : 0;
+
+ my ($v1, $v2);
+ $v1 = defined ($$i{'format'}) ? $$i{'format'} : "%s";
+ $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ $v2 = $$i{'value'};
+ $v2 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ my $r ='';
+ if ($v2) {
+ $r = &EvalExpr ($v2, $key, $num);
+ die "Error in section $report column $$i{'name'}. " .
+ "Invalid 'value' value.\n" unless defined $r;
+ }
+ $s .= sprintf $v1 . " ", $r
+ if $wtext && (($num <= $TOP_TEXT) || ($TOP_TEXT == -1));
+ if ($HTML && $whtml && ($num <= $TOP_HTML || $TOP_HTML == -1)) {
+ $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
+ $html .= "<TH ALIGN=\"CENTER\">$num</TH>" if $numbering && !$first;
+ my $temp = $first ? "RIGHT" : "LEFT";
+ $html .= sprintf "<TD ALIGN=\"$temp\">$v1</TD>", $r;
+ }
+ $first++;
+ }
+ $s =~ s/\s*$//;
+ print "$s\n" if $TEXT && ($num <= $TOP_TEXT || $TOP_TEXT == -1);
+ $s = '';
+ if ($HTML && ($num <= $TOP_HTML || $TOP_HTML == -1)) {
+ print HTML "<TR>$html</TR>\n";
+ $html = '';
+ }
+ }
+ print "\n" if $TEXT;
+ print HTML "<TR><TD></TD></TR>\n" if $HTML;
+ $first = 0;
+ foreach $i (@{$output{$report}{'column'}}) {
+ my $wtext = defined $$i{'text'} ? $$i{'text'} : 1;
+ $wtext = $wtext =~ m/^(1|true)$/io ? 1 : 0;
+ my $whtml = defined $$i{'html'} ? $$i{'html'} : 1;
+ $whtml = $whtml =~ m/^(1|true)$/io ? 1 : 0;
+
+ my ($v1, $v2);
+ $v1 = defined ($$i{'format_total'}) ? $$i{'format_total'} :
+ (defined ($$i{'format'}) ? $$i{'format'} : "%s");
+ $v1 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ $v2 = $$i{'total'} ||
+ die "Error in section $report column $$i{'name'}. " .
+ "Need a 'total' field.\n";
+ $v2 =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ my $r = '';
+ if ($v2) {
+ $r = &EvalExpr ($v2, $key, $num);
+ die "Error in section $report column $$i{'name'}. " .
+ "Invalid 'total' value.\n" unless defined $r;
+ }
+ $s .= sprintf $v1 . " ", $r if $wtext;
+ if ($HTML && $whtml) {
+ $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g;
+ my $temp = $first ? "RIGHT" : "LEFT";
+ $temp .= "\" COLSPAN=\"2" if $numbering && !$first;
+ $v1 =~ s|(.*)|<STRONG>$1</STRONG>|o unless $first;
+ $html .= sprintf "<TD ALIGN=\"$temp\">$v1</TD>", $r;
+ }
+ $first++;
+ }
+ $s =~ s/\s*$//;
+ print "$s\n" if $TEXT;
+ if ($HTML) {
+ print HTML "<TR>$html</TR>\n";
+ print HTML "</TABLE>\n</CENTER><P>\n";
+
+ my $i = 0;
+ while ($GRAPH && defined ${${$output{$report}{'graph'}}[$i]}{'type'}) {
+ my $type = ${${$output{$report}{'graph'}}[$i]}{'type'};
+ my ($title) = ${${$output{$report}{'graph'}}[$i]}{'title'} =~
+ m/^\"\s*(.*?)\s*\"$/o;
+ if ($type eq 'histo3d') {
+ my (@values, @colors, @labels);
+ my $num = 0;
+ my $j;
+ foreach $j (@{${${$output{$report}{'graph'}}[$i]}{'data'}}) {
+ $num++;
+ my ($h) = $$j{'value'} =~ m/^\"\s*(.*?)\s*\"$/o;
+ my %hh;
+ $h =~ s/^\%/\%$CLASS\:\:/ unless $h eq '%prog_type';
+ { local $^W = 0; no strict; %hh = eval $h }
+ push @values, \%hh;
+ my ($t) = $$j{'name'} =~ m/^\"\s*(.*?)\s*\"$/o;
+ push @labels, $t;
+ $t = $$j{'color'} ||
+ die "Error in section $report section 'graph'. " .
+ "No color specified for 'value' $$j{'value'}.\n";
+ $t =~ s/^\"\s*\#(.*?)\s*\"$/$1/o;
+ $t =~ m/^[\da-fA-F]{6}$/o ||
+ die "Error in section $report section 'graph'. " .
+ "Bad color for 'value' $$j{'value'}.\n";
+ my @c = map { hex $_ } ($t =~ m/^(..)(..)(..)$/);
+ push @colors, \@c;
+ }
+ $suffix = '' unless defined $suffix;
+ my $s = ($i ? $i : '') . $suffix;
+ print HTML "<CENTER><IMG ALT=\"$title\" ";
+ close HTML;
+ my $y = &Graph3d ("$IMG_dir/$report$s.$GD_FORMAT",
+ $title, $xmax, $num, @values, \@colors, \@labels);
+ open (HTML, ">> $HTML_output") ||
+ die "Error: cant open $HTML_output\n";
+ print HTML "WIDTH=\"$xmax\" HEIGHT=\"$y\" ";
+ print HTML "SRC=\"$IMG_pth$report$s.$GD_FORMAT\"></CENTER>\n";
+ }
+ elsif ($type eq 'histo') {
+ my (%values, %labels);
+ my $factor =
+ ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[1]}{'factor'}
+ || die "Error in section $report section 'graph'. " .
+ "No factor specified for 'value' " .
+ ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[1]}{'name'} .
+ ".\n";
+ $factor =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ my $labelx =
+ ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[0]}{'name'}
+ || die "Error in section $report section 'graph'. " .
+ "No name specified for value.\n";
+ $labelx =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ my $labely =
+ ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[1]}{'name'}
+ || die "Error in section $report section 'graph'. " .
+ "No name specified for value.\n";
+ $labely =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ my $t = ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[0]}{'value'}
+ || die "Error in section $report section 'graph'. " .
+ "No 'value' specified for " .
+ ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[0]}{'name'} .
+ ".\n";
+ $t =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ $t =~ s/^\%/\%$CLASS\:\:/ unless $t eq '%prog_type';
+ { local $^W = 0; no strict; %labels = eval $t }
+
+ $t = ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[1]}{'value'} ||
+ die "Error in section $report section 'graph'. " .
+ "No 'value' specified for " .
+ ${${${${$output{$report}{'graph'}}[$i]}{'data'}}[1]}{'name'} .
+ ".\n";
+ $t =~ s/^\"\s*(.*?)\s*\"$/$1/o;
+ $t =~ s/^\%/\%$CLASS\:\:/ unless $t eq '%prog_type';
+ { local $^W = 0; no strict; %values = eval $t }
+ my $s = ($i ? $i : '') . $suffix;
+ {
+ my $r;
+ close HTML;
+ $r = &Histo ("$IMG_dir/$report$s.$GD_FORMAT", $title, $xmax,
+ $factor, $labelx, $labely, \%values, \%labels);
+ open (HTML, ">> $HTML_output") ||
+ die "Error: cant open $HTML_output\n";
+ print HTML "<CENTER><IMG ALT=\"$title\" WIDTH=\"$xmax\" " .
+ "SRC=\"$IMG_pth$report$s.$GD_FORMAT\"></CENTER>\n" if $r;
+ }
+ }
+ elsif ($type eq 'piechart') {
+ print "Sorry, graph type 'piechart' not supported yet..\n";
+ }
+ else {
+ die "Error in section $report section 'graph'. " .
+ "Invalid 'type' value.\n"
+ }
+ $i++;
+ print HTML "<P>\n";
+ }
+ print HTML "\n<HR>\n";
+ }
+ }
+ close HTML if $HTML;
+}
+
+sub EvalExpr {
+ my $v = shift;
+ my ($key, $num, $key1) = @_;
+ my $key2;
+
+ $v =~ s/\n/ /smog;
+ $v =~ s/^\"(.*?)\"$/$1/o;
+ if ($key1) {
+ $key2 = $key;
+ $v =~ s/([^a-zA-Z_\-]?)total\s*\(\s*%/$1&ComputeTotalDouble\(\\%/og;
+ }
+ else {
+ $v =~ s/([^a-zA-Z_\-]?)total\s*\(\s*%/$1&ComputeTotal\(\\%/og;
+ # $v =~ s/([^a-zA-Z_\-]?)total\s*\(\s*%([^\)]*)\)/$1&ComputeTotal\("$2"\)/og;
+ }
+ $v =~ s/([^a-zA-Z_\-]?)bytes\s*\(\s*/$1&NiceByte\(/og;
+ $v =~ s/([^a-zA-Z_\-]?)time\s*\(\s*/$1&second2time\(/og;
+ $v =~ s/([^a-zA-Z_\-]?)time_ms\s*\(\s*/$1&ms2time\(/og;
+ # $v =~ s/([\$\%\@])/$1${CLASS}\:\:/og;
+ $v =~ s/([\$\%\@])([^{\s\d])/$1${CLASS}\:\:$2/og;
+ $v =~ s/([\$\%\@])${CLASS}\:\:(prog_(?:size|type)|key|sec_glob|num)/$1$2/og;
+ my $r;
+ # eval { local $^W = 0; no strict; ($r) = eval $v; };
+ eval " local \$^W = 0; no strict; (\$r) = $v; ";
+ $r = 0 unless defined $r;
+ $r;
+}
+
+sub NiceByte {
+ my $size = shift;
+ my $t;
+
+ $size = 0 unless defined $size;
+ $t = $size / 1024 / 1024 / 1024 > 1 ?
+ sprintf "%.1f GB", $size / 1024 / 1024 / 1024 :
+ ($size / 1024 / 1024 > 1 ? sprintf "%.1f MB", $size / 1024 / 1024 :
+ sprintf "%.1f KB", $size / 1024);
+ return $t;
+}
+
+sub kb2i {
+ my $s = shift;
+ my ($i, $u) = $s =~ m/^(\S+) (\S+)$/;
+ $i *= 1024 * 8 if $u =~ m/MB/o;
+ $i *= 1024 * 1024 * 8 if $u =~ m/GB/o;
+ return $i;
+}
+
+sub Decode_Config_File {
+ my $file = shift;
+ my ($line, $section);
+ my $linenum = 0;
+ my $info;
+ my @list;
+ open (FILE, "$file") || die "Can\'t open config file \"$file\". Abort.\n";
+ while (defined ($line = <FILE>)) {
+ $linenum++;
+ last if eof (FILE);
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ die "Error in $file line $linenum: must be 'section' instead of '$info'\n"
+ unless ($info eq 'section');
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ die "Error in $file line $linenum: invalid section name '$info'\n"
+ unless $info =~ /^\w+$/;
+ print "section $info {\n" if $DEBUG;
+ $section = $info;
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ die "Error in $file line $linenum: must be a '{' instead of '$info'\n"
+ unless ($info eq '{');
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ push @list, $section;
+ while ($info ne '}') { # it is a block
+ last if eof (FILE);
+ my $keyword = $info;
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ my $value = $info;
+ if ($info eq '{') { # it is a sub-block
+ my @a;
+ $output{$section}{$keyword} = \@a unless $output{$section}{$keyword};
+ my %hash;
+ print "\t$keyword {\n" if $DEBUG;
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ my @sublist; # to store the "data" blocks
+
+ while ($info ne '}') {
+ last if eof (FILE);
+ my $subkeyword = $info;
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ my $subvalue = $info;
+ if ($info eq '{') {
+ # it is a sub-sub-block
+ my %subhash;
+ print "\t\t$subkeyword {\n" if $DEBUG;
+ my @b;
+ $hash{$subkeyword} = \@b unless ${hash}{$subkeyword};
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ while ($info ne '}') {
+ last if eof (FILE);
+ my $subsubkeyword = $info;
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ my $subsubvalue = $info;
+ if ($info eq '{') {
+ die "Error in $file line $linenum: too many blocks.\n";
+ }
+ else {
+ ($info, $linenum, $line) =
+ &read_conf ($linenum, $line, \*FILE);
+ die "Error in $file line $linenum: must be a ';' instead " .
+ "of '$info'\n" unless ($info eq ';');
+ print "\t\t\t$subsubkeyword\t$subsubvalue;\n" if $DEBUG;
+ $subhash{$subsubkeyword} = $subsubvalue;
+ ($info, $linenum, $line) =
+ &read_conf ($linenum, $line, \*FILE);
+ }
+ }
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ die "Error in $file line $linenum: must be a ';' instead of " .
+ "'$info'\n" unless $info eq ';';
+ push @{$hash{$subkeyword}} , \%subhash;
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ print "\t\t};\n" if $DEBUG;
+ }
+ else {
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ die "Error in $file line $linenum: must be a ';' instead " .
+ "of '$info'\n" unless $info eq ';';
+ print "\t\t$subkeyword\t$subvalue;\n" if $DEBUG;
+ $hash{$subkeyword} = $subvalue;
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ }
+ }
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ die "Error in $file line $linenum: must be a ';' instead of '$info'\n"
+ unless $info eq ';';
+ push @{$output{$section}{$keyword}}, \%hash;
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ print "\t};\n" if $DEBUG;
+ }
+ else {
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ die "Error in $file line $linenum: must be a ';' instead of '$info'\n"
+ unless $info eq ';';
+ print "\t$keyword\t$value;\n" if $DEBUG;
+ $output{$section}{$keyword} = $value;
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ }
+ }
+ die "Error in $file line $linenum: must be a '}' instead of '$info'\n"
+ unless $info eq '}';
+ ($info, $linenum, $line) = &read_conf ($linenum, $line, \*FILE);
+ die "Error in $file line $linenum: must be a ';' instead of '$info'\n"
+ unless $info eq ';';
+ print "};\n\n" if $DEBUG;
+ }
+ close FILE;
+ $output{'_order_'} = \@list;
+}
+
+sub read_conf {
+ my ($linenum, $line, $file) = @_;
+ *FILE = *$file;
+
+ $line =~ s,^\s+,,o; # remove useless blanks
+ $line =~ s,^(\#|//).*$,,o; # remove comments (at the beginning)
+ while (($line =~ m/^$/o || $line =~ m/^\"[^\"]*$/o) && !(eof (FILE))) {
+ $line .= <FILE>; # read one line
+ $linenum++;
+ $line =~ s,^\s*,,om; # remove useless blanks
+ $line =~ s,^(\#|//).*$,,om; # remove comments (at the beginning)
+ }
+ $line =~ s/^( # at the beginning
+ [{};] # match '{', '}', or ';'
+ | # OR
+ \" # a double quoted string
+ (?:\\.|[^\"\\])*
+ \"
+ | # OR
+ [^{};\"\s]+ # a word
+ )\s*//mox;
+ my $info = $1;
+ if (defined $info && $info) {
+ chomp $info;
+ }
+ else {
+ warn "Syntax error in conf file line $linenum.\n";
+ }
+ return ($info, $linenum, $line);
+}
+
+sub GetValue {
+ my $v = shift;
+ my ($r) = $v =~ m/^(?:\"\s*)?(.*?)(?:\s*\")?$/so;
+ return $r;
+}
+
+sub Usage {
+ my ($base) = $0 =~ /([^\/]+)$/;
+ print "Usage: $base -f innreport.conf [-[no]options]\n";
+ print " where options are:\n";
+ print " -h (or -help) this help page\n";
+ print " -v display the version number of INNreport\n";
+ print " -config print INNreport configuration information\n";
+ print " -html HTML output";
+ print " [default]" if ($HTML);
+ print "\n";
+ print " -g want graphs";
+ print " [default]" if ($GRAPH);
+ print "\n";
+ print " -graph an alias for option -g\n";
+ print " -d directory directory for Web pages";
+ print "\n [default=$HTML_dir]"
+ if (defined ($HTML_dir));
+ print "\n";
+ print " -dir directory an alias for option -d\n";
+ print " -p directory pictures path (file space)";
+ print "\n [default=$IMG_dir]"
+ if (defined ($IMG_dir));
+ print "\n";
+ print " -path directory an alias for option -p\n";
+ print " -w directory pictures path (web space)";
+ print " [default=$IMG_pth]" if (defined ($IMG_pth));
+ print "\n";
+ print " -webpath directory an alias for option -w\n";
+ print "\n";
+ print " -i file Name of index file";
+ print " [default=$index]" if (defined ($index));
+ print "\n";
+ print " -index file an alias for option -i\n";
+ print " -a want to archive HTML results";
+ print " [default]" if ($ARCHIVE);
+ print "\n";
+ print " -archive an alias for option -a\n";
+ print " -c number how many report files to keep (0 = all)\n";
+ print " [default=$CYCLE]"
+ if (defined ($CYCLE));
+ print "\n";
+ print " -cycle number an alias for option -c\n";
+ print " -s char separator for filename";
+ print " [default=\"$SEPARATOR\"]\n";
+ print " -separator char an alias for option -s\n";
+ print " -unknown \"Unknown entries from news log file\"\n";
+ print " report";
+ print " [default]" if ($WANT_UNKNOWN);
+ print "\n";
+ print " -html-unknown Same as above, but in generated HTML output.";
+ print " [default]" if ($WANT_UNKNOWN);
+ print "\n";
+ print " -maxunrec Max number of unrecognized lines to display\n";
+ print " [default=$MAX_UNRECOGNIZED]"
+ if (defined ($MAX_UNRECOGNIZED));
+ print "\n";
+ print " -notdaily Never perform daily actions";
+ print " [default]" if $NOT_DAILY;
+ print "\n";
+ print " -casesensitive Case sensitive";
+ print " [default]" if ($CASE_SENSITIVE);
+ print "\n\n";
+ print "Use no in front of boolean options to unset them.\n";
+ print "For example, \"-html\" is set by default. Use \"-nohtml\" to remove this\n";
+ print "feature.\n";
+ exit 0;
+}
+
+sub Version {
+ print "\nThis is INNreport version $version\n\n";
+ print "Copyright 1996-1999, Fabien Tassin <fta\@sofaraway.org>\n";
+ exit 0;
+}
+
+sub Summary {
+ use Config;
+
+ # Convert empty arguments into null string ("")
+ my $i = 0;
+ foreach (@old_argv) {
+ $old_argv[$i] = '""' if $_ eq '';
+ $i++;
+ }
+
+ # Display the summary
+ print "\nSummary of my INNreport (version $version) configuration:\n";
+ print " General options:\n";
+ print " command line='@old_argv' (please, check this value)\n";
+ print " html=" . ($HTML?"yes":"no") . ", graph=" .
+ ($GRAPH?"yes":"no") . ", haveGD=" .
+ ($::HAVE_GD?"yes":"no") . "\n";
+ print " archive=" . ($ARCHIVE?"yes":"no") .
+ ", cycle=$CYCLE, separator=\"" . $SEPARATOR . "\"\n";
+ print " case_sensitive=" .
+ ($CASE_SENSITIVE?"yes":"no") . ", want_unknown=" .
+ ($WANT_UNKNOWN?"yes":"no") .
+ ", max_unrecog=$MAX_UNRECOGNIZED\n";
+ print " Paths:\n";
+ print " html_dir=$HTML_dir\n";
+ print " img_dir=$IMG_dir\n";
+ print " img_pth=$IMG_pth\n";
+ print " index=$index\n";
+ print " Platform:\n";
+ print " perl version $::Config{baserev} "
+ . "patchlevel $::Config{patchlevel} "
+ . "subversion $::Config{subversion}\n";
+ print " libperl=$::Config{libperl}, useshrplib=$::Config{useshrplib}, "
+ . "bincompat3=$::Config{bincompat3}\n";
+ print " osname=$::Config{osname}, osvers=$::Config{osvers}, "
+ . "archname=$::Config{archname}\n";
+ print " uname=$::Config{myuname}\n\n";
+
+ exit 0;
+}
+
+######################### End of File ##########################
--- /dev/null
+##########################################################
+# INN module for innreport (3.*).
+#
+# Sample file tested with INN 2.4, 2.3, 2.2, 1.7.2 and 1.5.1
+#
+# (c) 1997-1999 by Fabien Tassin <fta@sofaraway.org>
+# version 3.0.2
+##########################################################
+
+# TODO: add the map file.
+
+package innreport_inn;
+
+my $MIN = 1E10;
+my $MAX = -1;
+
+my %ctlinnd = ('a', 'addhist', 'D', 'allow',
+ 'b', 'begin', 'c', 'cancel',
+ 'u', 'changegroup', 'd', 'checkfile',
+ 'e', 'drop', 'f', 'flush',
+ 'g', 'flushlogs', 'h', 'go',
+ 'i', 'hangup', 's', 'mode',
+ 'j', 'name', 'k', 'newgroup',
+ 'l', 'param', 'm', 'pause',
+ 'v', 'readers', 't', 'refile',
+ 'C', 'reject', 'o', 'reload',
+ 'n', 'renumber', 'z', 'reserve',
+ 'p', 'rmgroup', 'A', 'send',
+ 'q', 'shutdown', 'B', 'signal',
+ 'r', 'throttle', 'w', 'trace',
+ 'x', 'xabort', 'y', 'xexec',
+ 'E', 'logmode', 'F', 'feedinfo',
+ 'T', 'filter', 'P', 'perl',);
+
+my %timer_names = (idle => 'idle',
+ hishave => 'history lookup',
+ hisgrep => 'history grep',
+ hiswrite => 'history write',
+ hissync => 'history sync',
+ nntpread => 'nntp read',
+ artparse => 'article parse',
+ artclean => 'article cleanup',
+ artwrite => 'article write',
+ artcncl => 'article cancel',
+ artlog => 'article logging',
+ sitesend => 'site send',
+ overv => 'overview write',
+ perl => 'perl filter',
+ python => 'python filter',
+ datamove => 'data move'
+);
+
+my %innfeed_timer_names = (
+ 'idle' => 'idle',
+ 'blstats' => 'backlog stats',
+ 'stsfile' => 'status file',
+ 'newart' => 'article new',
+ 'prepart' => 'article prepare',
+ 'readart' => 'article read',
+ 'read' => 'data read',
+ 'write' => 'data write',
+ 'cb' => 'callbacks',
+);
+
+my %nnrpd_timer_names = (
+ 'idle' => 'idle',
+ 'newnews' => 'newnews',
+);
+
+# init innd timer
+foreach (values %timer_names) {
+ $innd_time_min{$_} = $MIN;
+ $innd_time_max{$_} = $MAX;
+ $innd_time_time{$_} = 0; # to avoid a warning... Perl < 5.004
+ $innd_time_num{$_} = 0; # ...
+}
+$innd_time_times = 0; # ...
+
+# init innfeed timer
+foreach (values %innfeed_timer_names) {
+ $innfeed_time_min{$_} = $MIN;
+ $innfeed_time_max{$_} = $MAX;
+ $innfeed_time_time{$_} = 0; # to avoid a warning... Perl < 5.004
+ $innfeed_time_num{$_} = 0; # ...
+}
+$innfeed_time_times = 0; # ...
+
+# init nnrpd timer
+foreach (values %nnrpd_timer_names) {
+ $nnrpd_time_min{$_} = $MIN;
+ $nnrpd_time_max{$_} = $MAX;
+ $nnrpd_time_time{$_} = 0; # to avoid a warning... Perl < 5.004
+ $nnrpd_time_num{$_} = 0; # ...
+}
+$nnrpd_time_times = 0; # ...
+
+# collect: Used to collect the data.
+sub collect {
+ my ($day, $hour, $prog, $res, $left, $CASE_SENSITIVE) = @_;
+
+ return 1 if $left =~ /Reading config from (\S+)$/o;
+
+ ########
+ ## inn (from the "news" log file - not from "news.notice")
+ ##
+ if ($prog eq "inn") {
+ # accepted article
+ if ($res =~ m/[\+j]/o) {
+ $hour =~ s/:.*$//o;
+ $inn_flow{"$day $hour"}++;
+ $inn_flow_total++;
+
+ # Memorize the size. This can only be done with INN >= 1.5xx and
+ # DO_LOG_SIZE = DO.
+
+ # server <msg-id> size [feeds]
+ # or
+ # server <msg-id> (filename) size [feeds]
+
+ my ($s) = $left =~ /^\S+ \S+ (?:\(\S+\) )?(\d+)(?: |$)/o;
+ if ($s) {
+ $inn_flow_size{"$day $hour"} += $s;
+ $inn_flow_size_total += $s;
+ }
+ return 1;
+ }
+
+ # 437 Duplicate article
+ if ($left =~ /(\S+) <[^>]+> 437 Duplicate(?: article)?$/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $inn_badart{$server}++;
+ $inn_duplicate{$server}++;
+ return 1;
+ }
+ # 437 Unapproved for
+ if ($left =~ /(\S+) <[^>]+> 437 Unapproved for \"([^\"]+)\"$/o) {
+ my ($server, $group) = ($1, $2);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $inn_badart{$server}++;
+ $inn_unapproved{$server}++;
+ $inn_unapproved_g{$group}++;
+ return 1;
+ }
+ # 437 Too old -- ...
+ if ($left =~ /(\S+) <[^>]+> 437 Too old -- /o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $inn_badart{$server}++;
+ $inn_tooold{$server}++;
+ return 1;
+ }
+ # 437 Unwanted site ... in path
+ if ($left =~ /(\S+) <[^>]+> 437 Unwanted site (\S+) in path$/o) {
+ my ($server, $site) = ($1, $2);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $inn_badart{$server}++;
+ $inn_uw_site{$server}++;
+ $inn_site_path{$site}++;
+ return 1;
+ }
+ # 437 Unwanted newsgroup "..."
+ if ($left =~ /(\S+) <[^>]+> 437 Unwanted newsgroup \"(\S+)\"$/o) {
+ my ($server, $group) = ($1, $2);
+ ($group) = split(/,/, $group);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $inn_badart{$server}++;
+ $inn_uw_ng_s{$server}++;
+ $inn_uw_ng{$group}++;
+ return 1;
+ }
+ # 437 Unwanted distribution "..."
+ if ($left =~ /(\S+) <[^>]+> 437 Unwanted distribution \"(\S+)\"$/o) {
+ my ($server, $dist) = ($1, $2);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $inn_badart{$server}++;
+ $inn_uw_dist_s{$server}++;
+ $inn_uw_dist{$dist}++;
+ return 1;
+ }
+ # 437 Linecount x != y +- z
+ if ($left =~ /(\S+) <[^>]+> 437 Linecount/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $inn_badart{$server}++;
+ $inn_linecount{$server}++;
+ return 1;
+ }
+ # 437 No colon-space in "xxxx" header
+ if ($left =~ /(\S+) <[^>]+> 437 No colon-space in \"[^\"]+\" header/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $inn_badart{$server}++;
+ $innd_others{$server}++;
+ $innd_no_colon_space{$server}++;
+ return 1;
+ }
+ # 437 Article posted in the future -- "xxxxx"
+ if ($left =~ /(\S+) <[^>]+> 437 Article posted in the future -- \"[^\"]+\"/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_posted_future{$server}++;
+ $innd_others{$server}++;
+ $inn_badart{$server}++;
+ return 1;
+ }
+ # 437 article includes "....."
+ if ($left =~ /(\S+) <[^>]+> 437 article includes/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_strange_strings{$server}++;
+ $innd_others{$server}++;
+ $inn_badart{$server}++;
+ return 1;
+ }
+ # Cancelling <...>
+ if ($left =~ /(\S+) <[^>]+> Cancelling/o) {
+ return 1;
+ }
+ # all others are just counted as "Other"
+ if ($left =~ /(\S+) /o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $inn_badart{$server}++;
+ $innd_others{$server}++;
+ return 1;
+ }
+ }
+
+ ########
+ ## innd
+ if ($prog eq "innd") {
+ ## Note for innd logs:
+ ## there's a lot of entries detected but still not used
+ ## (because of a lack of interest).
+
+ # think it's a dotquad
+ return 1 if $left =~ /^think it\'s a dotquad$/o;
+ if ($left =~ /^SERVER /o) {
+ # SERVER perl filtering enabled
+ return 1 if $left =~ /^SERVER perl filtering enabled$/o;
+ # SERVER perl filtering disabled
+ return 1 if $left =~ /^SERVER perl filtering disabled$/o;
+ # SERVER Python filtering enabled
+ return 1 if $left =~ /^SERVER Python filtering enabled$/o;
+ # SERVER Python filtering disabled
+ return 1 if $left =~ /^SERVER Python filtering disabled$/o;
+ # SERVER cancelled +id
+ return 1 if $left =~ /^SERVER cancelled /o;
+ }
+ # Python filter
+ return 1 if $left =~ /^defined python methods$/o;
+ return 1 if $left =~ /^reloading pyfilter$/o;
+ return 1 if $left =~ /^reloaded pyfilter OK$/o;
+ return 1 if $left =~ /^python interpreter initialized OK$/o;
+ return 1 if $left =~ /^python method \w+ not found$/o;
+ return 1 if $left =~ /^python: First load, so I can do initialization stuff\.$/o;
+ return 1 if $left =~ /^python: filter_before_reload executing\.\.\.$/o;
+ return 1 if $left =~ /^python: I\'m just reloading, so skip the formalities\.$/o;
+ return 1 if $left =~ /^python: spamfilter successfully hooked into INN$/o;
+ return 1 if $left =~ /^python: state change from \w+ to \w+ - /o;
+ return 1 if $left =~ /^python: filter_close running, bye!$/o;
+ # rejecting[perl]
+ if ($left =~ /^rejecting\[perl\] <[^>]+> \d+ (.*)/o) {
+ $innd_filter_perl{$1}++;
+ return 1;
+ }
+ # rejecting[python]
+ if ($left =~ /^rejecting\[python\] <[^>]+> \d+ (.*)/o) {
+ $innd_filter_python{$1}++;
+ return 1;
+ }
+ # closed lost
+ return 1 if $left =~ /^\S+ closed lost \d+/o;
+ # new control command
+ if ($left =~ /^ctlinnd command (\w)(:.*)?/o) {
+ my $command = $1;
+ my $cmd = $ctlinnd{$command};
+ $cmd = $command unless $cmd;
+ return 1 if $cmd eq 'flush'; # to avoid a double count
+ $innd_control{"$cmd"}++;
+ return 1;
+ }
+ # old control command (by letter)
+ if ($left =~ /^(\w)$/o) {
+ my $command = $1;
+ my $cmd = $ctlinnd{$command};
+ $cmd = $command unless $cmd;
+ return 1 if $cmd eq 'flush'; # to avoid a double count
+ $innd_control{"$cmd"}++;
+ return 1;
+ }
+ # old control command (letter + reason)
+ if ($left =~ /^(\w):.*$/o) {
+ my $command = $1;
+ my $cmd = $ctlinnd{$command};
+ $cmd = $command unless $cmd;
+ return 1 if $cmd eq 'flush'; # to avoid a double count
+ $innd_control{"$cmd"}++;
+ return 1;
+ }
+ # opened
+ return 1 if $left =~ /\S+ opened \S+:\d+:file$/o;
+ # buffered
+ return 1 if $left =~ /\S+ buffered$/o;
+ # spawned
+ return 1 if $left =~ /\S+ spawned \S+:\d+:proc:\d+$/o;
+ return 1 if $left =~ /\S+ spawned \S+:\d+:file$/o;
+ # running
+ return 1 if $left =~ /\S+ running$/o;
+ # sleeping
+ if ($left =~ /(\S+):\d+:proc:\d+ sleeping$/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_blocked{$server}++;
+ return 1;
+ }
+ # blocked sleeping
+ if ($left =~ /(\S+):\d+:proc:\d+ blocked sleeping/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_blocked{$server}++;
+ return 1;
+ }
+ if ($left =~ /(\S+):\d+ blocked sleeping/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_blocked{$server}++;
+ return 1;
+ }
+ # restarted
+ return 1 if $left =~ m/^\S+ restarted$/o;
+ # starting
+ return 1 if $left =~ m/^\S+ starting$/o;
+ # readclose
+ return 1 if $left =~ m/^\S+:\d+ readclose+$/o;
+ # rejected 502
+ if ($left =~ m/^(\S+) rejected 502$/) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_no_permission{$server}++;
+ return 1;
+ }
+ # rejected 505
+ if ($left =~ m/^(\S+) rejected 505$/) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_too_many_connects_per_minute{$server}++;
+ return 1;
+ }
+ # connected
+ if ($left =~ /^(\S+) connected \d+/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_connect{$server}++;
+ return 1;
+ }
+ # closed (with times)
+ if ($left =~ /(\S+):\d+ closed seconds (\d+) accepted (\d+) refused (\d+) rejected (\d+) duplicate (\d+) accepted size (\d+) duplicate size (\d+)(?: rejected size (\d+))?$/o) {
+ my ($server, $seconds, $accepted, $refused, $rejected, $duplicate, $accptsize, $dupsize) =
+ ($1, $2, $3, $4, $5, $6, $7, $8);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_seconds{$server} += $seconds;
+ $innd_accepted{$server} += $accepted;
+ $innd_refused{$server} += $refused;
+ $innd_rejected{$server} += $rejected;
+ $innd_stored_size{$server} += $accptsize;
+ $innd_duplicated_size{$server} += $dupsize;
+ return 1;
+ } elsif ($left =~ /(\S+):\d+ closed seconds (\d+) accepted (\d+) refused (\d+) rejected (\d+)$/o) {
+ # closed (with times)
+ my ($server, $seconds, $accepted, $refused, $rejected) =
+ ($1, $2, $3, $4, $5);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_seconds{$server} += $seconds;
+ $innd_accepted{$server} += $accepted;
+ $innd_refused{$server} += $refused;
+ $innd_rejected{$server} += $rejected;
+ return 1;
+ }
+ # closed (without times (?))
+ return 1 if $left =~ m/\S+ closed$/o;
+ # closed (for a cancel feed - MODE CANCEL)
+ return 1 if $left =~ m/localhost:\d+ closed seconds \d+ cancels \d+$/o;
+ # checkpoint
+ return 1 if $left =~ m/^\S+:\d+ checkpoint /o;
+ # if ($left =~ /(\S+):\d+ checkpoint seconds (\d+) accepted (\d+)
+ # refused (\d+) rejected (\d+)$/) {
+ # # Skipped...
+ # my ($server, $seconds, $accepted, $refused, $rejected) =
+ # ($1, $2, $3, $4, $5);
+ # $innd_seconds{$server} += $seconds;
+ # $innd_accepted{$server} += $accepted;
+ # $innd_refused{$server} += $refused;
+ # $innd_rejected{$server} += $rejected;
+ # return 1;
+ # }
+
+ # flush
+ if ($left =~ /(\S+) flush$/o) {
+ $innd_control{"flush"}++;
+ return 1;
+ }
+ # flush-file
+ if ($left =~ /flush_file/) {
+ $innd_control{"flush_file"}++;
+ return 1;
+ }
+ # too many connections from site
+ if ($left =~ /too many connections from (\S+)/o) {
+ $innd_max_conn{$1}++;
+ return 1;
+ }
+ # overview exit 0 elapsed 23 pid 28461
+ return 1 if $left =~ m/\S+ exit \d+ .*$/o;
+ # internal rejecting huge article
+ if ($left =~ /(\S+) internal rejecting huge article/o) {
+ my $server = $1;
+ $server =~ s/:\d+$//o;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_huge{$server}++;
+ return 1;
+ }
+ # internal closing free channel
+ if ($left =~ /(\S+) internal closing free channel/o) {
+ $innd_misc{"Free channel"}++;
+ return 1;
+ }
+ # internal (other)
+ return 1 if $left =~ /\S+ internal/o;
+ # wakeup
+ return 1 if $left =~ /\S+ wakeup$/o;
+ # throttle
+ if ($left =~ /(\S+) throttled? /) {
+ $innd_control{"throttle"}++;
+ return 1;
+ }
+ # profile timer
+ # ME time X nnnn X(X) [...]
+ # The exact timers change from various versions of INN, so try to deal
+ # with this in a general fashion.
+ if ($left =~ m/^\S+\s+ # ME
+ time\ (\d+)\s+ # time
+ ((?:\S+\ \d+\(\d+\)\s*)+) # timer values
+ $/ox) {
+ $innd_time_times += $1;
+ my $timers = $2;
+
+ while ($timers =~ /(\S+) (\d+)\((\d+)\)\s*/g) {
+ my $name = $timer_names{$1} || $1;
+ my $average = $2 / ($3 || 1);
+ $innd_time_time{$name} += $2;
+ $innd_time_num{$name} += $3;
+ $innd_time_min{$name} = $average
+ if ($3 && $innd_time_min{$name} > $average);
+ $innd_time_max{$name} = $average
+ if ($3 && $innd_time_max{$name} < $average);
+ }
+ return 1;
+ }
+ # ME time xx idle xx(xx) [ bug ? a part of timer ?]
+ return 1 if $left =~ m/^ME time \d+ idle \d+\(\d+\)\s*$/o;
+ # ME HISstats x hitpos x hitneg x missed x dne
+ #
+ # from innd/his.c:
+ # HIShitpos: the entry existed in the cache and in history.
+ # HIShitneg: the entry existed in the cache but not in history.
+ # HISmisses: the entry was not in the cache, but was in the history file.
+ # HISdne: the entry was not in cache or history.
+ if ($left =~ m/^ME\ HISstats # ME HISstats
+ \ (\d+)\s+hitpos # hitpos
+ \ (\d+)\s+hitneg # hitneg
+ \ (\d+)\s+missed # missed
+ \ (\d+)\s+dne # dne
+ $/ox) {
+ $innd_his{'Positive hits'} += $1;
+ $innd_his{'Negative hits'} += $2;
+ $innd_his{'Cache misses'} += $3;
+ $innd_his{'Do not exist'} += $4;
+ return 1;
+ }
+ # SERVER history cache final: 388656 lookups, 1360 hits
+ if ($left =~ m/^SERVER history cache final: (\d+) lookups, (\d+) hits$/) {
+ $innd_cache{'Lookups'} += $1;
+ $innd_cache{'Hits'} += $2;
+ return 1;
+ }
+ # bad_hosts (appears after a "cant gesthostbyname" from a feed)
+ return 1 if $left =~ m/\S+ bad_hosts /o;
+ # cant read
+ return 1 if $left =~ m/\S+ cant read/o;
+ # cant write
+ return 1 if $left =~ m/\S+ cant write/o;
+ # cant flush
+ return 1 if $left =~ m/\S+ cant flush/o;
+ # spoolwake
+ return 1 if $left =~ m/\S+ spoolwake$/o;
+ # spooling
+ return 1 if $left =~ m/\S+ spooling/o;
+ # DEBUG
+ return 1 if $left =~ m/^DEBUG /o;
+ # NCmode
+ return 1 if $left =~ m/\S+ NCmode /o;
+ # outgoing
+ return 1 if $left =~ m/\S+ outgoing/o;
+ # inactive
+ return 1 if $left =~ m/\S+ inactive/o;
+ # timeout
+ return 1 if $left =~ m/\S+ timeout/o;
+ # lcsetup
+ return 1 if $left =~ m/\S+ lcsetup/o;
+ # rcsetup
+ return 1 if $left =~ m/\S+ rcsetup/o;
+ # flush_all
+ return 1 if $left =~ m/\S+ flush_all/o;
+ # buffered
+ return 1 if $left =~ m/\S+ buffered$/o;
+ # descriptors
+ return 1 if $left =~ m/\S+ descriptors/o;
+ # ccsetup
+ return 1 if $left =~ m/\S+ ccsetup/o;
+ # renumbering
+ return 1 if $left =~ m/\S+ renumbering/o;
+ # renumber
+ return 1 if $left =~ m/\S+ renumber /o;
+ # ihave from me
+ if ($left =~ m/\S+ ihave_from_me /o) {
+ $controlchan_ihave_site{'ME'}++;
+ return 1;
+ }
+ # sendme from me
+ if ($left =~ m/\S+ sendme_from_me /o) {
+ $controlchan_sendme_site{'ME'}++;
+ return 1;
+ }
+ # newgroup
+ if ($left =~ m/\S+ newgroup (\S+) as (\S)/o) {
+ $innd_newgroup{$1} = $2;
+ return 1;
+ }
+ # rmgroup
+ if ($left =~ m/\S+ rmgroup (\S+)$/o) {
+ $innd_rmgroup{$1}++;
+ return 1;
+ }
+ # changegroup
+ if ($left =~ m/\S+ change_group (\S+) to (\S)/o) {
+ $innd_changegroup{$1} = $2;
+ return 1;
+ }
+ # paused
+ if ($left =~ m/(\S+) paused /o) {
+ $innd_control{"paused"}++;
+ return 1;
+ }
+ # throttled
+ return 1 if $left =~ m/\S+ throttled/o;
+ # reload
+ if ($left =~ m/(\S+) reload/o) {
+ $innd_control{"reload"}++;
+ return 1;
+ }
+ # shutdown
+ if ($left =~ m/(\S+) shutdown/o) {
+ $innd_control{"shutdown"}++;
+ return 1;
+ }
+ # SERVER servermode paused
+ return 1 if ($left =~ /(\S+) servermode paused$/o);
+ # SERVER servermode running
+ return 1 if ($left =~ /(\S+) servermode running$/o);
+ # SERVER flushlogs paused
+ if ($left =~ /(\S+) flushlogs /) {
+ $innd_control{"flushlogs"}++;
+ return 1;
+ }
+ # think it's a dotquad
+ return 1 if $left =~ /think it\'s a dotquad: /o;
+ # bad_ihave
+ if ($left =~ /(\S+) bad_ihave /) {
+ my $server = $1;
+ $server =~ s/:\d+$//o;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_bad_ihave{$server}++;
+ return 1;
+ }
+ # bad_messageid
+ if ($left =~ /(\S+) bad_messageid/o) {
+ my $server = $1;
+ $server =~ s/:\d+$//o;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_bad_msgid{$server}++;
+ return 1;
+ }
+ # bad_sendme
+ if ($left =~ /(\S+) bad_sendme /o) {
+ my $server = $1;
+ $server =~ s/:\d+$//o;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_bad_sendme{$server}++;
+ return 1;
+ }
+ # bad_command
+ if ($left =~ /(\S+) bad_command /o) {
+ my $server = $1;
+ $server =~ s/:\d+$//o;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innd_bad_command{$server}++;
+ return 1;
+ }
+ # bad_newsgroup
+ if ($left =~ /(\S+) bad_newsgroup /o) {
+ my $server = $1;
+ $server =~ s/:\d+$//o;
+ $innd_bad_newsgroup{$server}++;
+ $server = lc $server unless $CASE_SENSITIVE;
+ return 1;
+ }
+ if ($left =~ m/ cant /o) {
+ # cant select Bad file number
+ if ($left =~ / cant select Bad file number/o) {
+ $innd_misc{"Bad file number"}++;
+ return 1;
+ }
+ # cant gethostbyname
+ if ($left =~ / cant gethostbyname/o) {
+ $innd_misc{"gethostbyname error"}++;
+ return 1;
+ }
+ # cant accept RCreader
+ if ($left =~ / cant accept RCreader /o) {
+ $innd_misc{"RCreader"}++;
+ return 1;
+ }
+ # cant sendto CCreader
+ if ($left =~ / cant sendto CCreader /o) {
+ $innd_misc{"CCreader"}++;
+ return 1;
+ }
+ # cant (other) skipped - not particularly interesting
+ return 1;
+ }
+ # bad_newsfeeds no feeding sites
+ return 1 if $left =~ /\S+ bad_newsfeeds no feeding sites/o;
+ # CNFS: cycbuff rollover - possibly interesting
+ return 1 if $left =~ /CNFS(?:-sm)?: cycbuff \S+ rollover to cycle/o;
+ # CNFS: CNFSflushallheads: flushing - possibly interesting
+ return 1 if $left =~ /CNFS(?:-sm)?: CNFSflushallheads: flushing /o;
+ # CNFS: metacycbuff rollover with SEQUENTIAL
+ return 1 if $left =~ /CNFS(?:-sm)?: metacycbuff \S+ cycbuff is moved to /o;
+ # Cleanfeed status reports
+ return 1 if $left =~ /^filter: status/o;
+ return 1 if $left =~ /^filter: Reloading bad files/o;
+ }
+ ########
+ ## innfeed
+ if ($prog eq "innfeed") {
+ # connected
+ if ($left =~ /(\S+):\d+ connected$/) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innfeed_connect{$server}++;
+ return 1;
+ }
+ # closed periodic
+ return 1 if $left =~ m/\S+:\d+ closed periodic$/o;
+ # periodic close
+ return 1 if $left =~ m/\S+:\d+ periodic close$/o;
+ # final (child)
+ return 1 if $left =~ m/\S+:\d+ final seconds \d+ offered \d+ accepted \d+ refused \d+ rejected \d+/o;
+ # global (real)
+ return 1 if $left =~ m/\S+ global seconds \d+ offered \d+ accepted \d+ refused \d+ rejected \d+ missing \d+/o;
+ # final (real) (new format)
+ if ($left =~ /(\S+) final seconds (\d+) offered (\d+) accepted (\d+) refused (\d+) rejected (\d+) missing (\d+) accsize (\d+) rejsize (\d+) spooled (\d+)/o) {
+ my ($server, $seconds, $offered, $accepted, $refused, $rejected,
+ $missing, $accepted_size, $rejected_size, $spooled) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innfeed_seconds{$server} += $seconds;
+ $innfeed_offered{$server} += $offered;
+ $innfeed_accepted{$server} += $accepted;
+ $innfeed_refused{$server} += $refused;
+ $innfeed_rejected{$server} += $rejected;
+ $innfeed_missing{$server} += $missing;
+ $innfeed_spooled{$server} += $spooled;
+ $innfeed_accepted_size{$server} += $accepted_size;
+ $innfeed_rejected_size{$server} += $rejected_size;
+ return 1;
+ } elsif ($left =~ /(\S+) final seconds (\d+) offered (\d+) accepted (\d+) refused (\d+) rejected (\d+) missing (\d+) spooled (\d+)/o) {
+ my ($server, $seconds, $offered, $accepted, $refused, $rejected,
+ $missing, $spooled) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innfeed_seconds{$server} += $seconds;
+ $innfeed_offered{$server} += $offered;
+ $innfeed_accepted{$server} += $accepted;
+ $innfeed_refused{$server} += $refused;
+ $innfeed_rejected{$server} += $rejected;
+ $innfeed_missing{$server} += $missing;
+ $innfeed_spooled{$server} += $spooled;
+ return 1;
+ }
+ # final (only seconds & spooled)
+ if ($left =~ /(\S+) final seconds (\d+) spooled (\d+)/o) {
+ my ($server, $seconds, $spooled) = ($1, $2, $3);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innfeed_seconds{$server} += $seconds;
+ $innfeed_spooled{$server} += $spooled;
+ return 1;
+ }
+ # checkpoint
+ return 1 if $left =~ m/\S+ checkpoint seconds/o;
+ # ME file xxxx shrunk from yyyy to zzz
+ if ($left =~ /^ME file (.*)\.output shrunk from (\d+) to (\d+)$/) {
+ my ($file, $s1, $s2) = ($1, $2, $3);
+ $file =~ s|^.*/([^/]+)$|$1|; # keep only the server name
+ $innfeed_shrunk{$file} += $s1 - $s2;
+ return 1;
+ }
+ # profile timer
+ # ME time X nnnn X(X) [...]
+ return 1 if $left =~ m/backlogstats/;
+ if ($left =~ m/^\S+\s+ # ME
+ time\ (\d+)\s+ # time
+ ((?:\S+\ \d+\(\d+\)\s*)+) # timer values
+ $/ox) {
+ $innfeed_time_times += $1;
+ my $timers = $2;
+
+ while ($timers =~ /(\S+) (\d+)\((\d+)\)\s*/g) {
+ my $name = $innfeed_timer_names{$1} || $1;
+ my $average = $2 / ($3 || 1);
+ $innfeed_time_time{$name} += $2;
+ $innfeed_time_num{$name} += $3;
+ $innfeed_time_min{$name} = $average
+ if ($3 && $innfeed_time_min{$name} > $average);
+ $innfeed_time_max{$name} = $average
+ if ($3 && $innfeed_time_max{$name} < $average);
+ }
+ return 1;
+ }
+ # xxx grabbing external tape file
+ return 1 if $left =~ m/ grabbing external tape file/o;
+ # hostChkCxns - maxConnections was
+ return 1 if $left =~ m/hostChkCxns - maxConnections was /o;
+ # cxnsleep
+ return 1 if $left =~ m/\S+ cxnsleep .*$/o;
+ # idle
+ return 1 if $left =~ m/\S+ idle tearing down connection$/o;
+ # remote
+ return 1 if $left =~ m/\S+ remote .*$/o;
+ # spooling
+ return 1 if $left =~ m/\S+ spooling no active connections$/o;
+ # ME articles total
+ return 1 if $left =~ m/(?:SERVER|ME) articles total \d+ bytes \d+/o;
+ # ME articles active
+ return 1 if $left =~ m/(?:SERVER|ME) articles active \d+ bytes \d+/o;
+ # connect : Connection refused
+ return 1 if $left =~ m/connect : Connection refused/o;
+ # connect : Network is unreachable
+ return 1 if $left =~ m/connect : Network is unreachable/o;
+ # connect : Address family not supported by protocol
+ return 1 if $left =~ m/connect : Address family not supported by protocol/o;
+ # connect : No route to host
+ return 1 if $left =~ m/connect : No route to host/o;
+ # connection vanishing
+ return 1 if $left =~ m/connection vanishing/o;
+ # can't resolve hostname
+ return 1 if $left =~ m/can\'t resolve hostname/o;
+ # new hand-prepared backlog file
+ return 1 if $left =~ m/new hand-prepared backlog file/o;
+ # flush re-connect failed
+ return 1 if $left =~ m/flush re-connect failed/o;
+ # internal QUIT while write pending
+ return 1 if $left =~ m/internal QUIT while write pending/o;
+ # ME source lost . Exiting
+ return 1 if $left =~ m/(?:SERVER|ME) source lost . Exiting/o;
+ # ME starting innfeed (+version & date)
+ return 1 if $left =~ m/(?:SERVER|ME) starting (?:innfeed|at)/o;
+ # ME finishing at (date)
+ return 1 if $left =~ m/(?:SERVER|ME) finishing at /o;
+ # mode no-CHECK entered
+ return 1 if $left =~ m/mode no-CHECK entered/o;
+ # mode no-CHECK exited
+ return 1 if $left =~ m/mode no-CHECK exited/o;
+ # closed
+ return 1 if $left =~ m/^(\S+) closed$/o;
+ # global (+ seconds offered accepted refused rejected missing)
+ return 1 if $left =~ m/^(\S+) global/o;
+ # idle connection still has articles
+ return 1 if $left =~ m/^(\S+) idle connection still has articles$/o;
+ # missing article for IHAVE-body
+ return 1 if $left =~ m/^(\S+) missing article for IHAVE-body$/o;
+ # cannot continue
+ return 1 if $left =~ m/^cannot continue/o;
+ if ($left =~ /^(?:SERVER|ME)/o) {
+ # ME dropping articles into ...
+ return 1 if $left =~ / dropping articles into /o;
+ # ME dropped ...
+ return 1 if $left =~ / dropped /o;
+ # ME internal bad data in checkpoint file
+ return 1 if $left =~ m/ internal bad data in checkpoint/o;
+ # ME two filenames for same article
+ return 1 if $left =~ m/ two filenames for same article/o;
+ # ME unconfigured peer
+ return 1 if $left =~ m/ unconfigured peer/o;
+ # exceeding maximum article size
+ return 1 if $left =~ m/ exceeding maximum article byte/o;
+ # no space left on device errors
+ return 1 if $left =~ m/ ioerr fclose/o;
+ return 1 if $left =~ m/ lock failed for host/o;
+ return 1 if $left =~ m/ lock file pid-write/o;
+ return 1 if $left =~ m/ locked cannot setup peer/o;
+ return 1 if $left =~ m/ received shutdown signal/o;
+ # unconfigured peer
+ return 1 if $left =~ m/ unconfigured peer/o;
+ # ME lock
+ return 1 if $left =~ m/ lock/o;
+ # ME exception: getsockopt (0): Socket operation on non-socket
+ return 1 if $left =~ m/ exception: getsockopt /o;
+ # ME config aborting fopen (...) Permission denied
+ return 1 if $left =~ m/ config aborting fopen /o;
+ # ME cant chmod innfeed.pid....
+ return 1 if $left =~ m/ cant chmod \S+\/innfeed.pid/o;
+ return 1 if $left =~ m/ tape open failed /o;
+ return 1 if $left =~ m/ oserr open checkpoint file:/o;
+ # ME finishing (quickly)
+ return 1 if $left =~ m/\(quickly\) /o;
+ # ME config: value of streaming is not a boolean
+ return 1 if $left =~ m/config: value of \S+ is not/o;
+ }
+ # hostChkCxn - now: x.xx, prev: x.xx, abs: xx, curr: x
+ return 1 if $left =~ m/ hostChkCxn - now/o;
+ # loading path_to_config_file/innfeed.conf
+ return 1 if $left =~ m/loading /o;
+ # Finnaly, to avoid problems with strange error lines, ignore them.
+ #return 1 if ($left =~ /ME /);
+ }
+ ########
+ ## innxmit
+ if ($prog eq "innxmit") {
+ # 437 Duplicate article
+ if ($left =~ /(\S+) rejected [^\s]+ \(.*?\) 437 Duplicate article$/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_badart{$server}++;
+ $innxmit_duplicate{$server}++;
+ return 1;
+ }
+ # 437 Unapproved for
+ if ($left =~ /(\S+) rejected [^\s]+ \(.*\) 437 Unapproved for \"(.*?)\"$/o) {
+ my ($server, $group) = ($1, $2);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_badart{$server}++;
+ $innxmit_unapproved{$server}++;
+ $innxmit_unapproved_g{$group}++;
+ return 1;
+ }
+ # 437 Too old -- ...
+ if ($left =~ /(\S+) rejected [^\s]+ \(.*\) 437 Too old -- \".*?\"$/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_badart{$server}++;
+ $innxmit_tooold{$server}++;
+ return 1;
+ }
+ # 437 Unwanted site ... in path
+ if ($left =~
+ /(\S+) rejected [^\s]+ \(.*?\) 437 Unwanted site (\S+) in path$/o) {
+ my ($server, $site) = ($1, $2);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_badart{$server}++;
+ $innxmit_uw_site{$server}++;
+ # $innxmit_site_path{$site}++;
+ return 1;
+ }
+ # 437 Unwanted newsgroup "..."
+ if ($left =~
+ /(\S+) rejected [^\s]+ \(.*?\) 437 Unwanted newsgroup \"(\S+)\"$/o) {
+ my ($server, $group) = ($1, $2);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_badart{$server}++;
+ $innxmit_uw_ng_s{$server}++;
+ $innxmit_uw_ng{$group}++;
+ return 1;
+ }
+ # 437 Unwanted distribution "..."
+ if ($left =~
+ /(\S+) rejected [^\s]+ \(.*?\) 437 Unwanted distribution \"(\S+)\"$/o) {
+ my ($server, $dist) = ($1, $2);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_badart{$server}++;
+ $innxmit_uw_dist_s{$server}++;
+ $innxmit_uw_dist{$dist}++;
+ return 1;
+ }
+ # xx rejected foo.bar/12345 (foo/bar/12345) 437 Unwanted distribution "..."
+ if ($left =~ /^(\S+) rejected .* 437 Unwanted distribution \"(\S+)\"$/o) {
+ my ($server, $dist) = ($1, $2);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_badart{$server}++;
+ $innxmit_uw_dist_s{$server}++;
+ $innxmit_uw_dist{$dist}++;
+ return 1;
+ }
+ # 437 Linecount x != y +- z
+ if ($left =~ /(\S+) rejected [^\s]+ \(.*?\) 437 Linecount/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_badart{$server}++;
+ $innxmit_linecount{$server}++;
+ return 1;
+ }
+ # 437 Newsgroup name illegal -- "xxx"
+ if ($left =~ /(\S+) rejected .* 437 Newsgroup name illegal -- "[^\"]*"$/) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_others{$server}++;
+ $innxmit_badart{$server}++;
+ return 1;
+ }
+ # Streaming retries
+ return 1 if ($left =~ /\d+ Streaming retries$/o);
+ # ihave failed
+ if ($left =~ /(\S+) ihave failed/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_ihfail{$server} = 1;
+ if ($left = /436 \S+ NNTP \S+ out of space/o) {
+ $innxmit_nospace{$server}++;
+ return 1;
+ }
+ if ($left = /400 \S+ space/o) {
+ $innxmit_nospace{$server}++;
+ return 1;
+ }
+ if ($left = /400 Bad file/o) {
+ $innxmit_crefused{$server}++;
+ return 1;
+ }
+ if ($left = /480 Transfer permission denied/o) {
+ $innxmit_crefused{$server}++;
+ return 1;
+ }
+ }
+ # stats (new format)
+ if ($left =~
+ /(\S+) stats offered (\d+) accepted (\d+) refused (\d+) rejected (\d+) missing (\d+) accsize (\d+) rejsize (\d+)$/o) {
+ my ($server, $offered, $accepted, $refused, $rejected, $missing, $accbytes, $rejbytes) =
+ ($1, $2, $3, $4, $5, $6, $7, $8);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_offered{$server} += $offered;
+ $innxmit_offered{$server} -= $innxmit_ihfail{$server}
+ if ($innxmit_ihfail{$server});
+ $innxmit_accepted{$server} += $accepted;
+ $innxmit_refused{$server} += $refused;
+ $innxmit_rejected{$server} += $rejected;
+ $innxmit_missing{$server} += $missing;
+ $innxmit_accepted_size{$server} += $accbytes;
+ $innxmit_rejected_size{$server} += $rejbytes;
+ $innxmit_site{$server}++;
+ $innxmit_ihfail{$server} = 0;
+ return 1;
+ }
+ # stats
+ if ($left =~
+ /(\S+) stats offered (\d+) accepted (\d+) refused (\d+) rejected (\d+)$/o) {
+ my ($server, $offered, $accepted, $refused, $rejected) =
+ ($1, $2, $3, $4, $5);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_offered{$server} += $offered;
+ $innxmit_offered{$server} -= $innxmit_ihfail{$server}
+ if ($innxmit_ihfail{$server});
+ $innxmit_accepted{$server} += $accepted;
+ $innxmit_refused{$server} += $refused;
+ $innxmit_rejected{$server} += $rejected;
+ $innxmit_site{$server}++;
+ $innxmit_ihfail{$server} = 0;
+ return 1;
+ }
+ # times
+ if ($left =~ /(\S+) times user (\S+) system (\S+) elapsed (\S+)$/o) {
+ my ($server, $user, $system, $elapsed) = ($1, $2, $3, $4);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_times{$server} += $elapsed;
+ return 1;
+ }
+ # connect & no space
+ if ($left =~ /(\S+) connect \S+ 400 No space/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_nospace{$server}++;
+ $innxmit_site{$server}++;
+ return 1;
+ }
+ # connect & NNTP no space
+ if ($left =~ /(\S+) connect \S+ 400 \S+ out of space/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_nospace{$server}++;
+ $innxmit_site{$server}++;
+ return 1;
+ }
+ # connect & loadav
+ if ($left =~ /(\S+) connect \S+ 400 loadav/o) {
+ my $server = $1;
+ if ($left =~ /expir/i) {
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_expire{$server}++;
+ $innxmit_site{$server}++;
+ return 1;
+ }
+ }
+ # connect 400 (other)
+ if ($left =~ /(\S+) connect \S+ 400/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_crefused{$server}++;
+ $innxmit_site{$server}++;
+ return 1;
+ }
+ # connect failed
+ if ($left =~ /(\S+) connect failed/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_cfail_host{$server}++;
+ $innxmit_site{$server}++;
+ return 1;
+ }
+ # authenticate failed
+ if ($left =~ /(\S+) authenticate failed/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_afail_host{$server}++;
+ $innxmit_site{$server}++;
+ return 1;
+ }
+ # xxx ihave failed 400 loadav [innwatch:hiload] yyy gt zzz
+ if ($left =~ /^(\S+) ihave failed 400 loadav/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $innxmit_hiload{$server}++;
+ return 1;
+ }
+ # ihave failed
+ return 1 if ($left =~ /\S+ ihave failed/o);
+ # requeued (....) 436 No space
+ return 1 if ($left =~ /\S+ requeued \S+ 436 No space/o);
+ # requeued (....) 400 No space
+ return 1 if ($left =~ /\S+ requeued \S+ 400 No space/o);
+ # requeued (....) 436 Can't write history
+ return 1 if ($left =~ /\S+ requeued \S+ 436 Can\'t write history/o);
+ # unexpected response code
+ return 1 if ($left =~ /unexpected response code /o);
+ }
+
+ ########
+ ## nntplink
+ if ($prog eq "nntplink") {
+ $left =~ s/^(\S+):/$1/;
+ # EOF
+ if ($left =~ /(\S+) EOF /o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_site{$server}++;
+ $nntplink_eof{$server}++;
+ return 1;
+ }
+ # Broken pipe
+ if ($left =~ /(\S+) Broken pipe$/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_site{$server}++;
+ $nntplink_bpipe{$server}++;
+ return 1;
+ }
+ # already running - won't die
+ return 1 if $left =~ /\S+ nntplink.* already running /o;
+ # connection timed out
+ if ($left =~ /(\S+) connection timed out/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_site{$server}++;
+ $nntplink_bpipe{$server}++;
+ return 1;
+ }
+ # greeted us with 400 No space
+ if ($left =~ /(\S+) greeted us with 400 No space/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_site{$server}++;
+ $nntplink_nospace{$server}++;
+ return 1;
+ }
+ # greeted us with 400 loadav
+ if ($left =~ /(\S+) greeted us with 400 loadav/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_site{$server}++;
+ $nntplink_hiload{$server}++;
+ return 1;
+ }
+ # greeted us with 400 (other)
+ if ($left =~ /(\S+) greeted us with 400/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_site{$server}++;
+ if ($left =~ /expir/i) {
+ $nntplink_expire{$server}++;
+ } else {
+ $nntplink_fail{$server}++;
+ }
+ return 1;
+ }
+ # greeted us with 502
+ if ($left =~ /(\S+) greeted us with 502/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_site{$server}++;
+ $nntplink_auth{$server}++;
+ return 1;
+ }
+ # sent authinfo
+ if ($left =~ /(\S+) sent authinfo/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_site{$server}++;
+ $nntplink_auth{$server}++;
+ return 1;
+ }
+ # socket()
+ if ($left =~ /(\S+) socket\(\): /o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_site{$server}++;
+ $nntplink_sockerr{$server}++;
+ return 1;
+ }
+ # select()
+ if ($left =~ /(\S+) select\(\) /o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_site{$server}++;
+ $nntplink_selecterr{$server}++;
+ return 1;
+ }
+ # sent IHAVE
+ if ($left =~ /(\S+) sent IHAVE/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_ihfail{$server}++;
+ if (($left =~ / 436 /) && ($left =~ / out of space /)) {
+ $nntplink_fake_connects{$server}++;
+ $nntplink_nospace{$server}++;
+ }
+ return 1;
+ }
+ # article .... failed(saved): 436 No space
+ if ($left =~ /(\S+) .* failed\(saved\): 436 No space$/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_nospace{$server}++;
+ return 1;
+ }
+ # article .. 400 No space left on device writing article file -- throttling
+ if ($left =~ /(\S+) .* 400 No space left on device writing article file -- throttling$/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_nospace{$server}++;
+ return 1;
+ }
+ # stats
+ if ($left =~ /(\S+) stats (\d+) offered (\d+) accepted (\d+) rejected (\d+) failed (\d+) connects$/o) {
+ my ($server, $offered, $accepted, $rejected, $failed, $connects) =
+ ($1, $2, $3, $4, $5, $6);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_offered{$server} += $offered - $nntplink_ihfail{$server}++;
+ $nntplink_accepted{$server} += $accepted;
+ $nntplink_rejected{$server} += $rejected;
+ $nntplink_failed{$server} += $failed;
+ $nntplink_connects{$server} += $connects;
+ $nntplink_ihfail{$server} = 0;
+ if ($nntplink_fake_connects{$server}) {
+ $nntplink_site{$server} += $nntplink_fake_connects{$server};
+ $nntplink_fake_connects{$server} = 0;
+ } else {
+ $nntplink_site{$server}++;
+ }
+ return 1;
+ }
+ # xmit
+ if ($left =~ /(\S+) xmit user (\S+) system (\S+) elapsed (\S+)$/o) {
+ my ($server, $user, $system, $elapsed) = ($1, $2, $3, $4);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_times{$server} += $elapsed;
+ return 1;
+ }
+ # xfer
+ return 1 if $left =~ /\S+ xfer/o;
+ # Links down .. x hours
+ if ($left =~ /(\S+) Links* down \S+ \d+/o) {
+ # Collected but not used
+ # my $server = $1;
+ # $server = lc $server unless $CASE_SENSITIVE;
+ # $nntplink_down{$server} += $hours;
+ return 1;
+ }
+ # 503 Timeout
+ if ($left =~ /^(\S+) \S+ \S+ \S+ 503 Timeout/o) {
+ # Collected but not used
+ # my $server = $1;
+ # $server = lc $server unless $CASE_SENSITIVE;
+ # $nntplink_timeout{$server}++;
+ return 1;
+ }
+ # read() error while reading reply
+ if ($left =~ /^(\S+): read\(\) error while reading reply/o) {
+ my $server = $1;
+ $server = lc $server unless $CASE_SENSITIVE;
+ $nntplink_failed{$server}++;
+ return 1;
+ }
+ # Password file xxxx not found
+ return 1 if $left =~ /^\S+ Password file \S+ not found/;
+ # No such
+ return 1 if $left =~ /^\S+ \S+ \S+ No such/;
+ # already running
+ return 1 if $left =~ /^\S+ \S+ already running/;
+ # error reading version from datafile
+ return 1 if $left =~ /error reading version from datafile/;
+ }
+ ########
+ ## nnrpd
+ if ($prog =~ /^nnrpd(?:-ssl)?$/)
+ {
+ # Fix a small bug of nnrpd (inn 1.4*)
+ $left =~ s/^ /\? /o;
+ # Another bug (in INN 1.5b1)
+ return 1 if $left =~ /^\020\002m$/o; # ^P^Bm
+ # bad_history at num for <ref>
+ return 1 if $left =~ /bad_history at \d+ for /o;
+ # timeout short
+ return 1 if $left =~ /\S+ timeout short$/o;
+ # < or > + (blablabla)
+ return 1 if $left =~ /^\S+ [\<\>] /o;
+ # cant opendir ... I/O error
+ return 1 if $left =~ /\S+ cant opendir \S+ I\/O error$/o;
+ # perl filtering enabled
+ return 1 if $left =~ /perl filtering enabled$/o;
+ # Python filtering enabled
+ return 1 if $left =~ /Python filtering enabled$/o;
+ return 1 if $left =~ /^python interpreter initialized OK$/o;
+ return 1 if $left =~ /^python method \S+ not found$/o;
+ return 1 if $left =~ /^python authenticate method succeeded, return code \d+, error string /o;
+ return 1 if $left =~ /^python access method succeeded$/o;
+ return 1 if $left =~ /^python dynamic method \(\w+ access\) succeeded, refusion string: /o;
+ return 1 if $left =~ /^python: .+ module successfully hooked into nnrpd$/o;
+ return 1 if $left =~ /^python: nnrpd .+ class instance created$/o;
+ return 1 if $left =~ /^python: n_a authenticate\(\) invoked: hostname \S+, ipaddress \S+, interface \S+, user /o;
+ return 1 if $left =~ /^python: n_a access\(\) invoked: hostname \S+, ipaddress \S+, interface \S+, user /o;
+ return 1 if $left =~ /^python: n_a dynamic\(\) invoked against type \S+, hostname \S+, ipaddress \S+, interface \S+, user /o;
+ return 1 if $left =~ /^python: authentication by username succeeded$/o;
+ return 1 if $left =~ /^python: authentication by username failed$/o;
+ return 1 if $left =~ /^python: authentication access by IP address succeeded$/o;
+ return 1 if $left =~ /^python: authentication access by IP address failed$/o;
+ return 1 if $left =~ /^python: dynamic access module successfully hooked into nnrpd$/o;
+ return 1 if $left =~ /^python: dynamic authorization access for read access granted$/o;
+ return 1 if $left =~ /^python: dynamic authorization access type is not known: /o;
+ # connect
+ if ($left =~ /(\S+) (\([0-9a-fA-F:.]*\) )?connect$/o) {
+ my $cust = $1;
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_dom_connect{$dom}++;
+ $nnrpd_connect{$cust}++;
+ return 1;
+ }
+ # group
+ if ($left =~ /(\S+) group (\S+) (\d+)$/o) {
+ my ($cust, $group, $num) = ($1, $2, $3);
+ if ($num) {
+ $nnrpd_group{$group} += $num;
+ my ($hierarchy) = $group =~ /^([^\.]+).*$/o;
+ $nnrpd_hierarchy{$hierarchy} += $num;
+ }
+ return 1;
+ }
+ # post failed
+ if ($left =~ /(\S+) post failed (.*)$/o) {
+ my ($cust, $error) = ($1, $2);
+ $nnrpd_post_error{$error}++;
+ return 1;
+ }
+ # post ok
+ return 1 if $left =~ /\S+ post ok/o;
+ # posts
+ if ($left =~ /(\S+) posts received (\d+) rejected (\d+)$/o) {
+ my ($cust, $received, $rejected) = ($1, $2, $3);
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_dom_post_ok{$dom} += $received;
+ $nnrpd_dom_post_rej{$dom} += $rejected;
+ $nnrpd_post_ok{$cust} += $received;
+ $nnrpd_post_rej{$cust} += $rejected;
+ return 1;
+ }
+ # noperm post without permission
+ if ($left =~ /(\S+) noperm post without permission/o) {
+ my $cust = $1;
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_dom_post_rej{$dom} ++;
+ $nnrpd_post_rej{$cust} ++;
+ return 1;
+ }
+ # no_permission
+ if ($left =~ /(\S+) no_(permission|access)$/o) {
+ my $cust = $1;
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_no_permission{$cust}++;
+ $nnrpd_dom_no_permission{$dom}++;
+ return 1;
+ }
+ # bad_auth
+ if ($left =~ /(\S+) bad_auth$/o) {
+ my $cust = $1;
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_dom_no_permission{$dom}++;
+ $nnrpd_no_permission{$cust}++;
+ return 1;
+ }
+ # Authentication failure
+ # User not known to the underlying authentication module
+ return 1 if $left =~ / ckpasswd: pam_authenticate failed: /o;
+ return 1 if $left =~ / ckpasswd: user .+ unknown$/o;
+ # authinfo
+ if ($left =~ /\S+ user (\S+)$/o) {
+ my $user = $1;
+ $nnrpd_auth{$user}++;
+ return 1;
+ }
+ # unrecognized + command
+ if ($left =~ /(\S+) unrecognized (.*)$/o) {
+ my ($cust, $error) = ($1, $2);
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $error = "_null command_" if ($error !~ /\S/);
+ $error =~ s/^(xmotd) .*$/$1/i if ($error =~ /^xmotd .*$/i);
+ $nnrpd_dom_unrecognized{$dom}++;
+ $nnrpd_unrecognized{$cust}++;
+ $nnrpd_unrecogn_cmd{$error}++;
+ return 1;
+ }
+ # exit
+ if ($left =~ /(\S+) exit articles (\d+) groups (\d+)$/o) {
+ my ($cust, $articles, $groups) = ($1, $2, $3);
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust) || '?';
+ $nnrpd_connect{$cust}++, $nnrpd_dom_connect{$dom}++ if $cust eq '?';
+ $nnrpd_groups{$cust} += $groups;
+ $nnrpd_dom_groups{$dom} += $groups;
+ $nnrpd_articles{$cust} += $articles;
+ $nnrpd_dom_articles{$dom} += $articles;
+ return 1;
+ }
+ # times
+ if ($left =~ /(\S+) times user (\S+) system (\S+) idle (\S+) elapsed (\S+)$/o) {
+ my ($cust, $user, $system, $idle, $elapsed) = ($1, $2, $3, $4, $5);
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_times{$cust} += $elapsed;
+ $nnrpd_resource_user{$cust} += $user;
+ $nnrpd_resource_system{$cust} += $system;
+ $nnrpd_resource_idle{$cust} += $idle;
+ $nnrpd_resource_elapsed{$cust} += $elapsed;
+ $nnrpd_dom_times{$dom} += $elapsed;
+ return 1;
+ }
+ # artstats
+ if ($left =~ /(\S+) artstats get (\d+) time (\d+) size (\d+)$/o) {
+ my ($cust, $articles, $time, $bytes) = ($1, $2, $3, $4);
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_bytes{$cust} += $bytes;
+ $nnrpd_dom_bytes{$dom} += $bytes;
+ return 1;
+ }
+ # timeout
+ if ($left =~ /(\S+) timeout$/o) {
+ my $cust = $1;
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_dom_timeout{$dom}++;
+ $nnrpd_timeout{$cust}++;
+ return 1;
+ }
+ # timeout in post
+ if ($left =~ /(\S+) timeout in post$/o) {
+ my $cust = $1;
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_dom_timeout{$dom}++;
+ $nnrpd_timeout{$cust}++;
+ return 1;
+ }
+ # can't read: Connection timed out
+ if ($left =~ /(\S+) can\'t read: Connection timed out$/o) {
+ my $cust = $1;
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_dom_timeout{$dom}++;
+ $nnrpd_timeout{$cust}++;
+ return 1;
+ }
+ # can't read: Operation timed out
+ if ($left =~ /(\S+) can\'t read: Operation timed out$/o) {
+ my $cust = $1;
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_dom_timeout{$dom}++;
+ $nnrpd_timeout{$cust}++;
+ return 1;
+ }
+ # can't read: Connection reset by peer
+ if ($left =~ /(\S+) can\'t read: Connection reset by peer$/o) {
+ my $cust = $1;
+ $cust = lc $cust unless $CASE_SENSITIVE;
+ my $dom = &host2dom($cust);
+ $nnrpd_dom_reset_peer{$dom}++;
+ $nnrpd_reset_peer{$cust}++;
+ return 1;
+ }
+ # can't read: Network is unreachable
+ return 1 if $left =~ /(\S+) can\'t read: Network is unreachable$/o;
+ # gethostbyaddr: xxx.yyy.zzz != a.b.c.d
+ if ($left =~ /^gethostbyaddr: (.*)$/o) {
+ my $msg = $1;
+ $nnrpd_gethostbyaddr{$msg}++;
+ return 1;
+ }
+ # cant gethostbyaddr
+ if ($left =~ /\? cant gethostbyaddr (\S+) .*$/o) {
+ my $ip = $1;
+ $nnrpd_gethostbyaddr{$ip}++;
+ return 1;
+ }
+ # cant getpeername
+ if ($left =~ /\? cant getpeername/o) {
+ # $nnrpd_getpeername++;
+ $nnrpd_gethostbyaddr{"? (can't getpeername)"}++;
+ return 1;
+ }
+ # can't getsockname
+ return 1 if $left =~ /^\S+ can\'t getsockname$/o;
+ # reverse lookup failed
+ return 1 if $left =~ /^\? reverse lookup for \S+ failed: .* -- using IP address for access$/o;
+ # profile timer
+ # ME time X nnnn X(X) [...]
+ # The exact timers change from various versions of INN, so try to deal
+ # with this in a general fashion.
+ if ($left =~ m/^\S+\s+ # ME
+ time\ (\d+)\s+ # time
+ ((?:\S+\ \d+\(\d+\)\s*)+) # timer values
+ $/ox) {
+ $nnrpd_time_times += $1;
+ my $timers = $2;
+
+ while ($timers =~ /(\S+) (\d+)\((\d+)\)\s*/g) {
+ my $name = $nnrpd_timer_names{$1} || $1;
+ my $average = $2 / ($3 || 1);
+ $nnrpd_time_time{$name} += $2;
+ $nnrpd_time_num{$name} += $3;
+ if ($3) {
+ my $min = $nnrpd_time_min{$name};
+ $nnrpd_time_min{$name} = $average
+ if (defined($min) && $min > $average);
+ my $max = $nnrpd_time_max{$name};
+ $nnrpd_time_max{$name} = $average
+ if (defined($max) && $max < $average);
+ }
+ }
+ return 1;
+ }
+ # ME dropping articles into ...
+ return 1 if $left =~ /ME dropping articles into /o;
+ # newnews (interesting but ignored till now)
+ return 1 if $left =~ /^\S+ newnews /o;
+ # cant fopen (ignored too)
+ return 1 if $left =~ /^\S+ cant fopen /o;
+ # can't read: No route to host
+ return 1 if $left =~ /can\'t read: No route to host/o;
+ # can't read: Broken pipe
+ return 1 if $left =~ /can\'t read: Broken pipe/o;
+ # eof in post
+ return 1 if $left =~ /^\S+ eof in post$/o;
+ # ioctl: ...
+ return 1 if $left =~ /^ioctl: /o;
+ # other stats
+ return 1 if $left =~ /^\S+ overstats count \d+ hit \d+ miss \d+ time \d+ size \d+ dbz \d+ seek \d+ get \d+ artcheck \d+$/o;
+ # starttls
+ return 1 if $left =~ /^starttls: \S+ with cipher \S+ \(\d+\/\d+ bits\) no authentication$/o;
+ }
+ ########
+ ## inndstart
+ if ($prog eq "inndstart") {
+ # cant bind Address already in use
+ # cant bind Permission denied
+ return 1 if $left =~ /cant bind /o;
+ # cant setgroups Operation not permitted
+ return 1 if $left =~ /cant setgroups /o;
+ }
+ ########
+ ## overchan
+ if ($prog eq "overchan") {
+ # times
+ if ($left =~ /timings (\d+) arts (\d+) of (\d+) ms$/o) {
+ my ($articles, $work_time, $run_time) = ($1, $2, $3);
+ # ??? What to do with numbers
+ return 1;
+ }
+ }
+ ########
+ ## batcher
+ if ($prog eq "batcher") {
+ # times
+ if ($left =~ /(\S+) times user (\S+) system (\S+) elapsed (\S+)$/o) {
+ my ($server, $user, $system, $elapsed) = ($1, $2, $3, $4);
+ $server = lc $server unless $CASE_SENSITIVE;
+ # $batcher_user{$server} += $user;
+ # $batcher_system{$server} += $system;
+ $batcher_elapsed{$server} += $elapsed;
+ return 1;
+ }
+ # stats
+ if ($left =~ /(\S+) stats batches (\d+) articles (\d+) bytes (\d+)$/o) {
+ my ($server, $batches, $articles, $bytes) = ($1, $2, $3, $4);
+ $server = lc $server unless $CASE_SENSITIVE;
+ $batcher_offered{$server} += $batches;
+ $batcher_articles{$server} += $articles;
+ $batcher_bytes{$server} += $bytes;
+ return 1;
+ }
+ }
+ ########
+ ## rnews
+ if ($prog eq "rnews") {
+ # rejected connection
+ if ($left =~ /rejected connection (.*)$/o) {
+ $rnews_rejected{$1}++;
+ return 1;
+ }
+ # cant open_remote
+ if ($left =~ /(cant open_remote .*)$/o) {
+ $rnews_rejected{$1}++;
+ return 1;
+ }
+ # rejected 437 Unwanted newsgroup
+ if ($left =~ /rejected 437 Unwanted newsgroup \"(.*)\"$/o) {
+ $rnews_bogus_ng{$1}++;
+ return 1;
+ }
+ # rejected 437 Unapproved for "xx"
+ if ($left =~ /rejected 437 Unapproved for \"(.*)\"$/o) {
+ $rnews_unapproved{$1}++;
+ return 1;
+ }
+ # rejected 437 Unwanted distribution
+ if ($left =~ /rejected 437 Unwanted distribution (.*)$/o) {
+ $rnews_bogus_dist{$1}++;
+ return 1;
+ }
+ # rejected 437 Bad "Date"
+ if ($left =~ /rejected 437 Bad \"Date\" (.*)$/o) {
+ $rnews_bogus_date{$1}++;
+ return 1;
+ }
+ # rejected 437 Article posted in the future
+ if ($left =~ /rejected 437 Article posted in the future -- \"(.*)\"$/o) {
+ $rnews_bogus_date{"(future) $1"}++;
+ return 1;
+ }
+ # rejected 437 Too old -- "..."
+ if ($left =~ /rejected 437 Too old -- (.*)$/o) {
+ $rnews_too_old++;
+ return 1;
+ }
+ # rejected 437 Linecount...
+ if ($left =~ /rejected 437 (Linecount) \d+ \!= \d+/o) {
+ $rnews_linecount++;
+ return 1;
+ }
+ # rejected 437 Duplicate
+ if ($left =~ /rejected 437 Duplicate$/o) {
+ $rnews_duplicate++;
+ return 1;
+ }
+ # rejected 437 Duplicate article
+ if ($left =~ /rejected 437 (Duplicate article)/o) {
+ $rnews_duplicate++;
+ return 1;
+ }
+ # rejected 437 No colon-space ...
+ if ($left =~ /rejected 437 No colon-space in \"(.*)\" header$/o) {
+ $rnews_no_colon_space++;
+ return 1;
+ }
+ # duplicate <msg-id> path..
+ if ($left =~ /^duplicate /o) {
+ $rnews_duplicate++;
+ return 1;
+ }
+ # offered <msg-id> feed
+ if ($left =~ /^offered \S+ (\S+)/o) {
+ my $host = $1;
+ $host = lc $host unless $CASE_SENSITIVE;
+ # Small hack used to join article spooled when innd is throttle.
+ # In this situation, the hostname is a 8 hex digits string
+ # To avoid confusions with real feeds, the first character is forced
+ # to be a '3' or a '4' (will work between 9/7/1995 and 13/7/2012).
+ $host = "Local postings" if $host =~ /^[34][0-9a-f]{7}$/;
+ $rnews_host{$host}++;
+ return 1;
+ }
+ # rejected 437 ECP rejected
+ return 1 if $left =~ m/rejected 437 ECP rejected/o;
+ # rejected 437 "Subject" header too long
+ return 1 if $left =~ m/header too long/o;
+ # rejected 437 Too long line in header 1163 bytes
+ return 1 if $left =~ m/rejected 437 Too long line in header/o;
+ # rejected 437 Too many newsgroups (meow)
+ return 1 if $left =~ m/rejected 437 Too many newsgroups/o;
+ # rejected 437 Space before colon in "<a" header
+ return 1 if $left =~ m/rejected 437 Space before colon in/o;
+ # rejected 437 EMP (phl)
+ return 1 if $left =~ m/rejected 437 EMP/o;
+ # rejected 437 Scoring filter (8)
+ return 1 if $left =~ m/rejected 437 Scoring filter/o;
+ # bad_article missing Message-ID
+ return 1 if $left =~ m/bad_article missing Message-ID/o;
+ # cant unspool saving to xxx
+ return 1 if $left =~ m/cant unspool saving to/o;
+ }
+
+ ###########
+ ## ncmspool
+ if ($prog eq "ncmspool") {
+ # <article> good signature from foo@bar.com
+ if ($left =~ /good signature from (.*)/o) {
+ $nocem_goodsigs{$1}++;
+ $nocem_totalgood++;
+ $nocem_lastid = $1;
+ return 1;
+ }
+ # <article> bad signature from foo@bar.com
+ if ($left =~ /bad signature from (.*)/o) {
+ $nocem_badsigs{$1}++;
+ $nocem_goodsigs{$1} = 0 unless ($nocem_goodsigs{$1});
+ $nocem_totalbad++;
+ $nocem_lastid = $1;
+ return 1;
+ }
+ # <article> contained 123 new 456 total ids
+ if ($left =~ /contained (\d+) new (\d+) total ids/o) {
+ $nocem_newids += $1;
+ $nocem_newids{$nocem_lastid} += $1;
+ $nocem_totalids += $2;
+ $nocem_totalids{$nocem_lastid} += $2;
+ return 1;
+ }
+ return 1;
+ }
+
+ ########
+ ## nocem
+ if ($prog eq "nocem") {
+ if ($left =~ /processed notice .* by (.*) \((\d+) ids,/o) {
+ $nocem_goodsigs{$1}++;
+ $nocem_totalgood++;
+ $nocem_lastid = $1;
+ $nocem_newids += $2;
+ $nocem_newids{$nocem_lastid} += $2;
+ $nocem_totalids += $2;
+ $nocem_totalids{$nocem_lastid} += $2;
+ return 1;
+ }
+ if ($left =~ /bad signature from (.*)/o) {
+ $nocem_badsigs{$1}++;
+ $nocem_goodsigs{$1} = 0 unless ($nocem_goodsigs{$1});
+ $nocem_totalbad++;
+ $nocem_lastid = $1;
+ return 1;
+ }
+ return 1;
+ }
+
+ ###########
+ ## controlchan
+ if ($prog eq "controlchan") {
+ # loaded /x/y/z/foo.pl
+ return 1 if $left =~ m/^loaded /;
+ # starting
+ return 1 if $left =~ m/^starting/;
+ # skipping rmgroup x@y (pgpverify failed) in <foo@bar>
+ if ($left =~ m/^skipping \S+ (\S+) \(pgpverify failed\) in /) {
+ $controlchan_skippgp{$1}++;
+ $controlchan_who{$1}++;
+ return 1;
+ }
+ if ($left =~ m/^control_(sendme|ihave), [^,]+, (\S+), doit,/o) {
+ if ($1 eq "sendme") {
+ $controlchan_sendme_site{$2}++;
+ } else {
+ $controlchan_ihave_site{$2}++;
+ }
+ return 1;
+ }
+ # control_XXgroup, foo.bar [moderated] who who /x/y/12, peer, action, 1
+ #
+ # Various other random junk can end up in the moderated field, like y,
+ # unmoderated, m, etc. depending on what the control message says. It
+ # can even have multiple words, which we still don't handle.
+ if ($left =~ m/^control_(\S+), # type of msg
+ \s(?:\S+)? # newsgroup name
+ (\s\S+)? # optional
+ \s(\S+) # e-mail
+ \s\S+ # e-mail
+ \s\S+, # filename
+ \s\S+, # server
+ \s([^=,]+(?:=\S+)?), # action
+ \s*(.*) # code
+ /x) {
+ if ($1 eq 'newgroup') {
+ $controlchan_new{$3}++;
+ } elsif ($1 eq 'rmgroup') {
+ $controlchan_rm{$3}++;
+ } else {
+ $controlchan_other{$3}++;
+ }
+ $controlchan_who{$3}++;
+ $controlchan_ok{$3} += $5;
+ my $action = $4;
+ my $email = $3;
+ $action =~ s/=.*//;
+ $controlchan_doit{$email}++ if $action eq 'doit';
+ return 1;
+ }
+ # checkgroups processed (no change or not)
+ return 1 if $left =~ /^checkgroups by \S+ processed/o;
+ }
+
+ ###########
+ ## crosspost
+ if ($prog eq "crosspost") {
+ # seconds 1001 links 3182 0 symlinks 0 0 mkdirs 0 0
+ # missing 13 toolong 0 other 0
+ if ($left =~ /^seconds\ (\d+)
+ \ links\ (\d+)\ (\d+)
+ \ symlinks\ (\d+)\ (\d+)
+ \ mkdirs\ (\d+)\ (\d+)
+ \ missing\ (\d+)
+ \ toolong\ (\d+)
+ \ other\ (\d+)
+ $/ox) {
+ $crosspost_time += $1;
+ $crosspost{'Links made'} += $2;
+ $crosspost{'Links failed'} += $3;
+ $crosspost{'Symlinks made'} += $4;
+ $crosspost{'Symlinks failed'} += $5;
+ $crosspost{'Mkdirs made'} += $6;
+ $crosspost{'Mkdirs failed'} += $7;
+ $crosspost{'Files missing'} += $8;
+ $crosspost{'Paths too long'} += $9;
+ $crosspost{'Others'} += $10;
+ return 1;
+ }
+ }
+
+ ###########
+ ## cnfsstat
+ if ($prog eq "cnfsstat") {
+ # Class ALT for groups matching "alt.*" article size min/max: 0/1048576
+ # Buffer T3, len: 1953 Mbytes, used: 483.75 Mbytes (24.8%) 0 cycles
+ if ($left =~ m|^Class\ (\S+)\ for\ groups\ matching\ \S+
+ (\ article\ size\ min/max:\ \d+/\d+)?
+ \ Buffer\ (\S+),
+ \ len:\ ([\d.]+)\s+Mbytes,
+ \ used:\ ([\d.]+)\ Mbytes\ \(\s*[\d.]+%\)
+ \s+(\d+)\ cycles\s*
+ $|ox) {
+ my ($class, $buffer, $size, $used, $cycles) = ($1, $3, $4, $5, $6);
+ my ($h, $m, $s) = $hour =~ m/^(\d+):(\d+):(\d+)$/;
+ my $time = $h * 3600 + $m * 60 + $s;
+ $size *= 1024 * 1024;
+ $used *= 1024 * 1024;
+ $cnfsstat{$buffer} = $class;
+
+ # If the size changed, invalidate all of our running fill rate stats.
+ if (!exists($cnfsstat_size{$buffer}) || $size != $cnfsstat_size{$buffer}) {
+ delete $cnfsstat_rate{$buffer};
+ delete $cnfsstat_samples{$buffer};
+ delete $cnfsstat_time{$buffer};
+ $cnfsstat_size{$buffer} = $size;
+ }
+ elsif ($cnfsstat_time{$buffer}) {
+ # We want to gather the rate at which cycbuffs fill. Store a
+ # running total of bytes/second and a total number of samples.
+ # Ideally we'd want a weighted average of those samples by the
+ # length of the sample period, but we'll ignore that and assume
+ # cnfsstat runs at a roughly consistent interval.
+ my ($period, $added);
+ $period = $time - $cnfsstat_time{$buffer};
+ $period = 86400 - $cnfsstat_time{$buffer} + $time if $period <= 0;
+ $added = $used - $cnfsstat_used{$buffer};
+ if ($cycles > $cnfsstat_cycles{$buffer}) {
+ $added += $size * ($cycles - $cnfsstat_cycles{$buffer});
+ }
+ if ($added > 0) {
+ $cnfsstat_rate{$buffer} += $added / $period;
+ $cnfsstat_samples{$buffer}++;
+ }
+ }
+ $cnfsstat_used{$buffer} = $used;
+ $cnfsstat_cycles{$buffer} = $cycles;
+ $cnfsstat_time{$buffer} = $time;
+ return 1;
+ }
+ }
+
+ # Ignore following programs :
+ return 1 if ($prog eq "uxfxn");
+ return 1 if ($prog eq "beverage");
+ return 1 if ($prog eq "newsx");
+ return 1 if ($prog eq "demmf");
+ return 1 if ($prog eq "nnnn");
+ return 1 if ($prog eq "slurp");
+ return 0;
+}
+
+#################################
+# Adjust some values..
+
+sub adjust {
+ my ($first_date, $last_date) = @_;
+
+ my $nnrpd_doit = 0;
+ my $curious;
+
+ {
+ my $serv;
+ if (%nnrpd_connect) {
+ my $c = keys (%nnrpd_connect);
+ foreach $serv (keys (%nnrpd_connect)) {
+ my $dom = &host2dom($serv);
+ if ($nnrpd_no_permission{$serv}) {
+ $nnrpd_dom_connect{$dom} -= $nnrpd_connect{$serv}
+ if defined $nnrpd_dom_connect{$dom} && defined $nnrpd_connect{$serv};
+ $nnrpd_dom_groups{$dom} -= $nnrpd_groups{$serv}
+ if defined $nnrpd_dom_groups{$dom} && defined $nnrpd_groups{$serv};
+ $nnrpd_dom_times{$dom} -= $nnrpd_times{$serv}
+ if defined $nnrpd_dom_times{$dom};
+ $nnrpd_connect{$serv} -= $nnrpd_no_permission{$serv};
+ $nnrpd_groups{$serv} -= $nnrpd_no_permission{$serv}
+ if defined $nnrpd_groups{$serv};
+ delete $nnrpd_connect{$serv} unless $nnrpd_connect{$serv};
+ delete $nnrpd_groups{$serv} unless $nnrpd_groups{$serv};
+ delete $nnrpd_times{$serv} unless $nnrpd_times{$serv};
+ delete $nnrpd_usr_times{$serv} unless $nnrpd_usr_times{$serv};
+ delete $nnrpd_sys_times{$serv} unless $nnrpd_sys_times{$serv};
+ delete $nnrpd_dom_connect{$dom} unless $nnrpd_dom_connect{$dom};
+ delete $nnrpd_dom_groups{$dom} unless $nnrpd_dom_groups{$dom};
+ delete $nnrpd_dom_times{$dom} unless $nnrpd_dom_times{$dom};
+ $c--;
+ }
+ $nnrpd_doit++
+ if $nnrpd_groups{$serv} || $nnrpd_post_ok{$serv};
+ }
+ undef %nnrpd_connect unless $c;
+ }
+ foreach $serv (keys (%nnrpd_groups)) {
+ $curious = "ok" unless $nnrpd_groups{$serv} || $nnrpd_post_ok{$serv} ||
+ $nnrpd_articles{$serv};
+ }
+ }
+
+ # Fill some hashes
+ {
+ my $key;
+ foreach $key (keys (%innd_connect)) {
+ $innd_offered{$key} = ($innd_accepted{$key} || 0)
+ + ($innd_refused{$key} || 0)
+ + ($innd_rejected{$key} || 0);
+ $innd_offered_size{$key} = ($innd_stored_size{$key} || 0)
+ + ($innd_duplicated_size{$key} || 0);
+ }
+
+
+ # adjust min/max of innd timer stats.
+ if (%innd_time_min) {
+ foreach $key (keys (%innd_time_min)) {
+ $innd_time_min{$key} = 0 if ($innd_time_min{$key} == $MIN);
+ $innd_time_max{$key} = 0 if ($innd_time_max{$key} == $MAX);
+
+ #$innd_time_min{$key} /= 1000;
+ #$innd_time_max{$key} /= 1000;
+ }
+ }
+ if (%innfeed_time_min) {
+ foreach $key (keys (%innfeed_time_min)) {
+ $innfeed_time_min{$key} = 0 if ($innfeed_time_min{$key} == $MIN);
+ $innfeed_time_max{$key} = 0 if ($innfeed_time_max{$key} == $MAX);
+ }
+ }
+ if (%nnrpd_time_min) {
+ foreach $key (keys (%nnrpd_time_min)) {
+ $nnrpd_time_min{$key} = 0 if ($nnrpd_time_min{$key} == $MIN);
+ $nnrpd_time_max{$key} = 0 if ($nnrpd_time_max{$key} == $MAX);
+ }
+ }
+ # remove the innd timer stats if not used.
+ unless ($innd_time_times) {
+ undef %innd_time_min;
+ undef %innd_time_max;
+ undef %innd_time_num;
+ undef %innd_time_time;
+ }
+ # same thing for innfeed timer
+ unless ($innfeed_time_times) {
+ undef %innfeed_time_min;
+ undef %innfeed_time_max;
+ undef %innfeed_time_num;
+ undef %innfeed_time_time;
+ }
+ # same thing for nnrpd timer
+ unless ($nnrpd_time_times) {
+ undef %nnrpd_time_min;
+ undef %nnrpd_time_max;
+ undef %nnrpd_time_num;
+ undef %nnrpd_time_time;
+ }
+
+ # adjust the crosspost stats.
+ if (%crosspost) {
+ foreach $key (keys (%crosspost)) {
+ $crosspost_times{$key} = $crosspost_time ?
+ sprintf "%.2f", $crosspost{$key} / $crosspost_time * 60 : "?";
+ }
+ }
+ }
+
+ if (%inn_flow) {
+ my ($prev_dd, $prev_d, $prev_h) = ("", -1, -1);
+ my $day;
+ foreach $day (sort datecmp keys (%inn_flow)) {
+ my ($r, $h) = $day =~ /^(.*) (\d+)$/;
+ my $d = index ("JanFebMarAprMayJunJulAugSepOctNovDec",
+ substr ($r,0,3)) / 3 * 31 + substr ($r, 4, 2);
+ $prev_h = $h if ($prev_h == -1);
+ if ($prev_d == -1) {
+ $prev_d = $d;
+ $prev_dd = $r;
+ }
+ if ($r eq $prev_dd) { # Same day and same month ?
+ if ($h != $prev_h) {
+ if ($h == $prev_h + 1) {
+ $prev_h++;
+ }
+ else {
+ my $j;
+ for ($j = $prev_h + 1; $j < $h; $j++) {
+ my $t = sprintf "%02d", $j;
+ $inn_flow{"$r $t"} = 0;
+ }
+ $prev_h = $h;
+ }
+ }
+ }
+ else {
+ my $j;
+ # then end of the first day...
+ for ($j = ($prev_h == 23) ? 24 : $prev_h + 1; $j < 24; $j++) {
+ my $t = sprintf "%02d", $j;
+ $inn_flow{"$prev_dd $t"} = 0;
+ }
+
+ # all the days between (if any)
+ # well, we can forget them as it is supposed to be a tool
+ # launched daily.
+
+ # the beginning of the last day..
+ for ($j = 0; $j < $h; $j++) {
+ my $t = sprintf "%02d", $j;
+ $inn_flow{"$r $t"} = 0;
+ }
+ $prev_dd = $r;
+ $prev_d = $d;
+ $prev_h = $h;
+ }
+ }
+ my $first = 1;
+ my (%hash, %hash_time, %hash_size, $date, $delay);
+ foreach $day (sort datecmp keys (%inn_flow)) {
+ my ($r, $h) = $day =~ /^(.*) (\d+)$/o;
+ if ($first) {
+ $first = 0;
+ my ($t) = $first_date =~ m/:(\d\d:\d\d)$/o;
+ $date = "$day:$t - $h:59:59";
+ $t =~ m/(\d\d):(\d\d)/o;
+ $delay = 3600 - $1 * 60 - $2;
+ }
+ else {
+ $date = "$day:00:00 - $h:59:59";
+ $delay = 3600;
+ }
+ $hash{$date} = $inn_flow{$day};
+ $hash_size{$date} = $inn_flow_size{$day};
+ $inn_flow_labels{$date} = $h;
+ $hash_time{$date} = $delay;
+ }
+ my ($h, $t) = $last_date =~ m/ (\d+):(\d\d:\d\d)$/o;
+ my ($h2) = $date =~ m/ (\d+):\d\d:\d\d /o;
+ my $date2 = $date;
+ $date2 =~ s/$h2:59:59$/$h:$t/;
+ $hash{$date2} = $hash{$date};
+ delete $hash{"$date"};
+ $hash_size{$date2} = $hash_size{$date};
+ delete $hash_size{"$date"};
+ $t =~ m/(\d\d):(\d\d)/o;
+ $hash_time{$date2} = $hash_time{$date} - ($h2 == $h) * 3600 + $1 * 60 + $2;
+ delete $hash_time{"$date"};
+ $inn_flow_labels{$date2} = $h;
+ %inn_flow = %hash;
+ %inn_flow_time = %hash_time;
+ %inn_flow_size = %hash_size;
+ }
+
+ if (%innd_bad_ihave) {
+ my $key;
+ my $msg = 'Bad ihave control messages received';
+ foreach $key (keys %innd_bad_ihave) {
+ $innd_misc_stat{$msg}{$key} = $innd_bad_ihave{$key};
+ }
+ }
+ if (%innd_bad_msgid) {
+ my $key;
+ my $msg = 'Bad Message-ID\'s offered';
+ foreach $key (keys %innd_bad_msgid) {
+ $innd_misc_stat{$msg}{$key} = $innd_bad_msgid{$key};
+ }
+ }
+ if (%innd_bad_sendme) {
+ my $key;
+ my $msg = 'Ignored sendme control messages received';
+ foreach $key (keys %innd_bad_sendme) {
+ $innd_misc_stat{$msg}{$key} = $innd_bad_sendme{$key};
+ }
+ }
+ if (%innd_bad_command) {
+ my $key;
+ my $msg = 'Bad command received';
+ foreach $key (keys %innd_bad_command) {
+ $innd_misc_stat{$msg}{$key} = $innd_bad_command{$key};
+ }
+ }
+ if (%innd_bad_newsgroup) {
+ my $key;
+ my $msg = 'Bad newsgroups received';
+ foreach $key (keys %innd_bad_newsgroup) {
+ $innd_misc_stat{$msg}{$key} = $innd_bad_newsgroup{$key};
+ }
+ }
+ if (%innd_posted_future) {
+ my $key;
+ my $msg = 'Article posted in the future';
+ foreach $key (keys %innd_posted_future) {
+ $innd_misc_stat{$msg}{$key} = $innd_posted_future{$key};
+ }
+ }
+ if (%innd_no_colon_space) {
+ my $key;
+ my $msg = 'No colon-space in header';
+ foreach $key (keys %innd_no_colon_space) {
+ $innd_misc_stat{$msg}{$key} = $innd_no_colon_space{$key};
+ }
+ }
+ if (%innd_huge) {
+ my $key;
+ my $msg = 'Huge articles';
+ foreach $key (keys %innd_huge) {
+ $innd_misc_stat{$msg}{$key} = $innd_huge{$key};
+ }
+ }
+ if (%innd_blocked) {
+ my $key;
+ my $msg = 'Blocked server feeds';
+ foreach $key (keys %innd_blocked) {
+ $innd_misc_stat{$msg}{$key} = $innd_blocked{$key};
+ }
+ }
+ if (%innd_strange_strings) {
+ my $key;
+ my $msg = 'Including strange strings';
+ foreach $key (keys %innd_strange_strings) {
+ $innd_misc_stat{$msg}{$key} = $innd_strange_strings{$key};
+ }
+ }
+ if (%rnews_bogus_ng) {
+ my $key;
+ my $msg = 'Unwanted newsgroups';
+ foreach $key (keys %rnews_bogus_ng) {
+ $rnews_misc{$msg}{$key} = $rnews_bogus_ng{$key};
+ }
+ }
+ if (%rnews_bogus_dist) {
+ my $key;
+ my $msg = 'Unwanted distributions';
+ foreach $key (keys %rnews_bogus_dist) {
+ $rnews_misc{$msg}{$key} = $rnews_bogus_dist{$key};
+ }
+ }
+ if (%rnews_unapproved) {
+ my $key;
+ my $msg = 'Articles unapproved';
+ foreach $key (keys %rnews_unapproved) {
+ $rnews_misc{$msg}{$key} = $rnews_unapproved{$key};
+ }
+ }
+ if (%rnews_bogus_date) {
+ my $key;
+ my $msg = 'Bad Date';
+ foreach $key (keys %rnews_bogus_date) {
+ $rnews_misc{$msg}{$key} = $rnews_bogus_date{$key};
+ }
+ }
+
+ $rnews_misc{'Too old'}{'--'} = $rnews_too_old if $rnews_too_old;
+ $rnews_misc{'Bad linecount'}{'--'} = $rnews_linecount if $rnews_linecount;
+ $rnews_misc{'Duplicate articles'}{'--'} = $rnews_duplicate
+ if $rnews_duplicate;
+ $rnews_misc{'No colon-space'}{'--'} = $rnews_no_colon_space
+ if $rnews_no_colon_space;
+
+ if (%nnrpd_groups) {
+ my $key;
+ foreach $key (keys (%nnrpd_connect)) {
+ unless ($nnrpd_groups{"$key"} || $nnrpd_post_ok{"$key"} ||
+ $nnrpd_articles{"$key"}) {
+ $nnrpd_curious{$key} = $nnrpd_connect{$key};
+ undef $nnrpd_connect{$key};
+ }
+ }
+ }
+}
+
+sub report_unwanted_ng {
+ my $file = shift;
+ open (FILE, "$file") && do {
+ while (<FILE>) {
+ my ($c, $n) = $_ =~ m/^\s*(\d+)\s+(.*)$/;
+ next unless defined $n;
+ $n =~ s/^newsgroup //o; # for pre 1.8 logs
+ $inn_uw_ng{$n} += $c;
+ }
+ close (FILE);
+ };
+
+ unlink ("${file}.old");
+ rename ($file, "${file}.old");
+
+ open (FILE, "> $file") && do {
+ my $g;
+ foreach $g (sort {$inn_uw_ng{$b} <=> $inn_uw_ng{$a}} (keys (%inn_uw_ng))) {
+ printf FILE "%d %s\n", $inn_uw_ng{$g}, $g;
+ }
+ close (FILE);
+ chmod(0660, "$file");
+ };
+ unlink ("${file}.old");
+}
+
+###########################################################################
+
+# Compare 2 dates (+hour)
+sub datecmp {
+ # ex: "May 12 06" for May 12, 6:00am
+ local($[) = 0;
+ # The 2 dates are near. The range is less than a few days that's why we
+ # can cheat to determine the order. It is only important if one date
+ # is in January and the other in December.
+
+ my($date1) = substr($a, 4, 2) * 24;
+ my($date2) = substr($b, 4, 2) * 24;
+ $date1 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($a,0,3)) * 288;
+ $date2 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($b,0,3)) * 288;
+ if ($date1 - $date2 > 300 * 24) {
+ $date2 += 288 * 3 * 12;
+ }
+ elsif ($date2 - $date1 > 300 * 24) {
+ $date1 += 288 * 3 * 12;
+ }
+ $date1 += substr($a, 7, 2);
+ $date2 += substr($b, 7, 2);
+ $date1 - $date2;
+}
+
+sub host2dom {
+ my $host = shift;
+
+ $host =~ m/^[^\.]+(.*)/;
+ $host =~ m/^[\d\.]+$/ ? "unresolved" : $1 ? "*$1" : "?";
+}
+
+1;
--- /dev/null
+/* tls.c --- TLSv1 functions
+ Copyright (C) 2000 Kenichi Okada <okada@opaopa.org>
+
+ Author: Kenichi Okada <okada@opaopa.org>
+ Created: 2000-02-22
+
+ Keywords: TLS, OpenSSL
+
+ Commentary:
+
+ [RFC 2246] "The TLS Protocol Version 1.0"
+ by Christopher Allen <callen@certicom.com> and
+ Tim Dierks <tdierks@certicom.com> (1999/01)
+
+ [RFC 2595] "Using TLS with IMAP, POP3 and ACAP"
+ by Chris Newman <chris.newman@innosoft.com> (1999/06)
+
+*/
+
+#include <sys/types.h>
+#include "config.h"
+#include "nnrpd.h"
+
+#ifdef HAVE_SSL
+
+/* System library. */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+#endif
+
+/* outside the ifdef so `make depend` works even ifndef HAVE_SSL */
+#include "tls.h"
+#include "sasl_config.h"
+
+#ifdef HAVE_SSL
+
+/* We must keep some of the info available */
+static const char hexcodes[] = "0123456789ABCDEF";
+
+static bool tls_initialized = false;
+
+static int verify_depth;
+static int verify_error = X509_V_OK;
+static int do_dump = 0;
+static SSL_CTX *CTX = NULL;
+SSL *tls_conn = NULL;
+
+#define CCERT_BUFSIZ 256
+
+int tls_serverengine = 0;
+int tls_serveractive = 0; /* available or not */
+char *tls_peer_subject = NULL;
+char *tls_peer_issuer = NULL;
+char *tls_peer_fingerprint = NULL;
+
+int tls_clientactive = 0; /* available or not */
+char *tls_peer_CN = NULL;
+char *tls_issuer_CN = NULL;
+
+const char *tls_protocol = NULL;
+const char *tls_cipher_name = NULL;
+int tls_cipher_usebits = 0;
+int tls_cipher_algbits = 0;
+
+
+int tls_loglevel = 0;
+
+
+/* taken from OpenSSL apps/s_cb.c
+ * tim - this seems to just be giving logging messages
+ */
+
+static void apps_ssl_info_callback(SSL * s, int where, int ret)
+{
+ const char *str;
+ int w;
+
+ if (tls_loglevel==0) return;
+
+ w = where & ~SSL_ST_MASK;
+
+ if (w & SSL_ST_CONNECT)
+ str = "SSL_connect";
+ else if (w & SSL_ST_ACCEPT)
+ str = "SSL_accept";
+ else
+ str = "undefined";
+
+ if (where & SSL_CB_LOOP) {
+ if (tls_serverengine && (tls_loglevel >= 2))
+ Printf("%s:%s", str, SSL_state_string_long(s));
+ } else if (where & SSL_CB_ALERT) {
+ str = (where & SSL_CB_READ) ? "read" : "write";
+ if ((tls_serverengine && (tls_loglevel >= 2)) ||
+ ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY))
+ Printf("SSL3 alert %s:%s:%s", str,
+ SSL_alert_type_string_long(ret),
+ SSL_alert_desc_string_long(ret));
+ } else if (where & SSL_CB_EXIT) {
+ if (ret == 0)
+ Printf("%s:failed in %s",
+ str, SSL_state_string_long(s));
+ else if (ret < 0) {
+ Printf("%s:error in %s",
+ str, SSL_state_string_long(s));
+ }
+ }
+}
+
+
+/*
+ * Hardcoded DH parameter files, from OpenSSL.
+ * For information on how these files were generated, see
+ * "Assigned Number for SKIP Protocols"
+ * (http://www.skip-vpn.org/spec/numbers.html.
+ */
+static const char file_dh512[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
+XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
+-----END DH PARAMETERS-----\n";
+
+static const char file_dh1024[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
+jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
+ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
+-----END DH PARAMETERS-----\n";
+
+static const char file_dh2048[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
+89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
+T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
+zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
+Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
+CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
+-----END DH PARAMETERS-----\n";
+
+static const char file_dh4096[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
+l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
+Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
+Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
+VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
+alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
+sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
+ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
+OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
+AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
+KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
+-----END DH PARAMETERS-----\n";
+
+/*
+ * Load hardcoded DH parameters.
+ */
+static DH *
+load_dh_buffer (const char *buffer, size_t len)
+{
+ BIO *bio;
+ DH *dh = NULL;
+
+ bio = BIO_new_mem_buf((char *) buffer, len);
+ if (bio == NULL)
+ return NULL;
+ dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
+/* if (dh == NULL) log error */
+ BIO_free(bio);
+
+ return dh;
+}
+
+/*
+ * Generate empheral DH key. Because this can take a long
+ * time to compute, we use precomputed parameters of the
+ * common key sizes.
+ *
+ * These values can be static (once loaded or computed) since
+ * the OpenSSL library can effectively generate random keys
+ * from the information provided.
+ *
+ * EDH keying is slightly less efficient than static RSA keying,
+ * but it offers Perfect Forward Secrecy (PFS).
+ *
+ * FIXME: support user-specified files, to eliminate risk of
+ * "small group" attacks.
+ */
+static DH *tmp_dh_cb(SSL *s UNUSED, int export UNUSED, int keylength)
+{
+ DH *r = NULL;
+ static DH *dh = NULL;
+ static DH *dh512 = NULL;
+ static DH *dh1024 = NULL;
+ static DH *dh2048 = NULL;
+ static DH *dh4096 = NULL;
+
+ switch (keylength)
+ {
+ case 512:
+ if (dh512 == NULL)
+ dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
+ r = dh512;
+ break;
+ case 1024:
+ if (dh1024 == NULL)
+ dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
+ r = dh1024;
+ break;
+ case 2048:
+ if (dh2048 == NULL)
+ dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
+ r = dh2048;
+ break;
+ case 4096:
+ if (dh4096 == NULL)
+ dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
+ r = dh4096;
+ break;
+ default:
+ /* we should check current keylength vs. requested keylength */
+ /* also, this is an extremely expensive operation! */
+ dh = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
+ r = dh;
+ }
+
+ return r;
+}
+
+/* taken from OpenSSL apps/s_cb.c */
+
+static int verify_callback(int ok, X509_STORE_CTX * ctx)
+{
+ char buf[256];
+ X509 *err_cert;
+ int err;
+ int depth;
+
+ syslog(L_NOTICE,"Doing a peer verify");
+
+ err_cert = X509_STORE_CTX_get_current_cert(ctx);
+ err = X509_STORE_CTX_get_error(ctx);
+ depth = X509_STORE_CTX_get_error_depth(ctx);
+
+ X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
+ if ((tls_serveractive) && (tls_loglevel >= 1))
+ Printf("Peer cert verify depth=%d %s", depth, buf);
+ if (ok==0)
+ {
+ syslog(L_NOTICE, "verify error:num=%d:%s", err,
+ X509_verify_cert_error_string(err));
+
+ if (verify_depth >= depth) {
+ ok = 0;
+ verify_error = X509_V_OK;
+ } else {
+ ok = 0;
+ verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ }
+ }
+ switch (ctx->error) {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
+ syslog(L_NOTICE, "issuer= %s", buf);
+ break;
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ syslog(L_NOTICE, "cert not yet valid");
+ break;
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ syslog(L_NOTICE, "cert has expired");
+ break;
+ }
+ if ((tls_serveractive) && (tls_loglevel >= 1))
+ Printf("verify return:%d", ok);
+
+ return (ok);
+}
+
+
+/*
+ * taken from OpenSSL crypto/bio/b_dump.c, modified to save a lot of strcpy
+ * and strcat by Matti Aarnio.
+ */
+
+#define TRUNCATE
+#define DUMP_WIDTH 16
+
+static int tls_dump(const char *s, int len)
+{
+ int ret = 0;
+ char buf[160 + 1];
+ char *ss;
+ int i;
+ int j;
+ int rows;
+ int trunc;
+ unsigned char ch;
+
+ trunc = 0;
+
+
+#ifdef TRUNCATE
+ for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
+ trunc++;
+#endif
+
+ rows = (len / DUMP_WIDTH);
+ if ((rows * DUMP_WIDTH) < len)
+ rows++;
+
+ for (i = 0; i < rows; i++) {
+ buf[0] = '\0'; /* start with empty string */
+ ss = buf;
+
+ sprintf(ss, "%04x ", i * DUMP_WIDTH);
+ ss += strlen(ss);
+ for (j = 0; j < DUMP_WIDTH; j++) {
+ if (((i * DUMP_WIDTH) + j) >= len) {
+ strcpy(ss, " ");
+ } else {
+ ch = ((unsigned char) *((const char *)(s) + i * DUMP_WIDTH + j))
+ & 0xff;
+ sprintf(ss, "%02x%c", ch, j == 7 ? '|' : ' ');
+ ss += 3;
+ }
+ }
+ ss += strlen(ss);
+ *ss+= ' ';
+ for (j = 0; j < DUMP_WIDTH; j++) {
+ if (((i * DUMP_WIDTH) + j) >= len)
+ break;
+ ch = ((unsigned char) *((const char *)(s) + i * DUMP_WIDTH + j))
+ & 0xff;
+ *ss+= (((ch >= ' ') && (ch <= '~')) ? ch : '.');
+ if (j == 7) *ss+= ' ';
+ }
+ *ss = 0;
+ /*
+ * if this is the last call then update the ddt_dump thing so that
+ * we will move the selection point in the debug window
+ */
+ if (tls_loglevel>0)
+ Printf("%s", buf);
+ ret += strlen(buf);
+ }
+#ifdef TRUNCATE
+ if (trunc > 0) {
+ snprintf(buf, sizeof(buf), "%04x - <SPACES/NULS>\n", len+ trunc);
+ if (tls_loglevel>0)
+ Printf("%s", buf);
+ ret += strlen(buf);
+ }
+#endif
+ return (ret);
+}
+
+ /*
+ * Set up the cert things on the server side. We do need both the
+ * private key (in key_file) and the cert (in cert_file).
+ * Both files may be identical.
+ *
+ * This function is taken from OpenSSL apps/s_cb.c
+ */
+
+static int set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file)
+{
+ struct stat buf;
+
+ if (cert_file != NULL) {
+ if (SSL_CTX_use_certificate_file(ctx, cert_file,
+ SSL_FILETYPE_PEM) <= 0) {
+ syslog(L_ERROR, "unable to get certificate from '%s'", cert_file);
+ return (0);
+ }
+ if (key_file == NULL)
+ key_file = cert_file;
+
+ /* check ownership and permissions of key file */
+ if (lstat(key_file, &buf) == -1) {
+ syslog(L_ERROR, "unable to stat private key '%s'", key_file);
+ return (0);
+ }
+ if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) != 0 ||
+ buf.st_uid != getuid()) {
+ syslog(L_ERROR, "bad ownership or permissions on private key"
+ " '%s': private key must be mode 600 and owned by "
+ NEWSUSER, cert_file);
+ return (0);
+ }
+
+ if (SSL_CTX_use_PrivateKey_file(ctx, key_file,
+ SSL_FILETYPE_PEM) <= 0) {
+ syslog(L_ERROR, "unable to get private key from '%s'", key_file);
+ return (0);
+ }
+ /* Now we know that a key and cert have been set against
+ * the SSL context */
+ if (!SSL_CTX_check_private_key(ctx)) {
+ syslog(L_ERROR, "Private key does not match the certificate public key");
+ return (0);
+ }
+ }
+ return (1);
+}
+
+
+
+ /*
+ * This is the setup routine for the SSL server. As smtpd might be called
+ * more than once, we only want to do the initialization one time.
+ *
+ * The skeleton of this function is taken from OpenSSL apps/s_server.c.
+
+ * returns -1 on error
+ */
+
+int tls_init_serverengine(int verifydepth,
+ int askcert,
+ int requirecert,
+ char *tls_CAfile,
+ char *tls_CApath,
+ char *tls_cert_file,
+ char *tls_key_file
+ )
+{
+ int off = 0;
+ int verify_flags = SSL_VERIFY_NONE;
+ char *CApath;
+ char *CAfile;
+ char *s_cert_file;
+ char *s_key_file;
+ struct stat buf;
+
+ if (tls_serverengine)
+ return (0); /* already running */
+
+ if (tls_loglevel >= 2)
+ Printf("starting TLS engine");
+
+ SSL_load_error_strings();
+ SSLeay_add_ssl_algorithms();
+
+ CTX = SSL_CTX_new(SSLv23_server_method());
+ if (CTX == NULL) {
+ return (-1);
+ };
+
+ off |= SSL_OP_ALL; /* Work around all known bugs */
+ SSL_CTX_set_options(CTX, off);
+ SSL_CTX_set_info_callback(CTX, apps_ssl_info_callback);
+ SSL_CTX_sess_set_cache_size(CTX, 128);
+
+ if (strlen(tls_CAfile) == 0)
+ CAfile = NULL;
+ else
+ CAfile = tls_CAfile;
+ if (strlen(tls_CApath) == 0)
+ CApath = NULL;
+ else
+ CApath = tls_CApath;
+
+ if ((!SSL_CTX_load_verify_locations(CTX, CAfile, CApath)) ||
+ (!SSL_CTX_set_default_verify_paths(CTX))) {
+ if (tls_loglevel >= 2)
+ Printf("TLS engine: cannot load CA data\n");
+ return (-1);
+ }
+
+ if (strlen(tls_cert_file) == 0)
+ s_cert_file = NULL;
+ else
+ s_cert_file = tls_cert_file;
+ if (strlen(tls_key_file) == 0)
+ s_key_file = NULL;
+ else
+ s_key_file = tls_key_file;
+
+ if (!set_cert_stuff(CTX, s_cert_file, s_key_file)) {
+ if (tls_loglevel >= 2)
+ Printf("TLS engine: cannot load cert/key data\n");
+ return (-1);
+ }
+
+ /* load some randomization data from /dev/urandom, if it exists */
+ /* FIXME: should also check for ".rand" file, update it on exit */
+ if (stat("/dev/urandom", &buf) == 0)
+ RAND_load_file("/dev/urandom", 16 * 1024);
+
+ SSL_CTX_set_tmp_dh_callback(CTX, tmp_dh_cb);
+ SSL_CTX_set_options(CTX, SSL_OP_SINGLE_DH_USE);
+
+ verify_depth = verifydepth;
+ if (askcert!=0)
+ verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
+ if (requirecert)
+ verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
+ | SSL_VERIFY_CLIENT_ONCE;
+ SSL_CTX_set_verify(CTX, verify_flags, verify_callback);
+
+ SSL_CTX_set_client_CA_list(CTX, SSL_load_client_CA_file(CAfile));
+
+ tls_serverengine = 1;
+ return (0);
+}
+
+
+/*
+** The function called by nnrpd to initialize the TLS support. Calls
+** tls_init_server_engine and checks the result. On any sort of failure,
+** nnrpd will exit.
+*/
+void
+tls_init(void)
+{
+ int ssl_result;
+
+ if (tls_initialized)
+ return;
+ sasl_config_read();
+ ssl_result = tls_init_serverengine(5, /* depth to verify */
+ 0, /* can client auth? */
+ 0, /* required client to auth? */
+ (char *)sasl_config_getstring("tls_ca_file", ""),
+ (char *)sasl_config_getstring("tls_ca_path", ""),
+ (char *)sasl_config_getstring("tls_cert_file", ""),
+ (char *)sasl_config_getstring("tls_key_file", ""));
+ if (ssl_result == -1) {
+ Reply("%d Error initializing TLS\r\n", NNTP_STARTTLS_BAD_VAL);
+ syslog(L_ERROR, "error initializing TLS: "
+ "[CA_file: %s] [CA_path: %s] [cert_file: %s] [key_file: %s]",
+ sasl_config_getstring("tls_ca_file", ""),
+ sasl_config_getstring("tls_ca_path", ""),
+ sasl_config_getstring("tls_cert_file", ""),
+ sasl_config_getstring("tls_key_file", ""));
+ ExitWithStats(1, false);
+ }
+ tls_initialized = true;
+}
+
+
+/* taken from OpenSSL apps/s_cb.c */
+
+static long bio_dump_cb(BIO * bio, int cmd, const char *argp, int argi,
+ long argl UNUSED, long ret)
+{
+ if (!do_dump)
+ return (ret);
+
+ if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
+ Printf("read from %08X [%08lX] (%d bytes => %ld (0x%X))", (unsigned int) bio, (long unsigned int) argp,
+ argi, ret, (unsigned int) ret);
+ tls_dump(argp, (int) ret);
+ return (ret);
+ } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
+ Printf("write to %08X [%08lX] (%d bytes => %ld (0x%X))", (unsigned int) bio, (long unsigned int)argp,
+ argi, ret, (unsigned int) ret);
+ tls_dump(argp, (int) ret);
+ }
+ return (ret);
+}
+
+ /*
+ * This is the actual startup routine for the connection. We expect
+ * that the buffers are flushed and the "220 Ready to start TLS" was
+ * send to the client, so that we can immediately can start the TLS
+ * handshake process.
+ *
+ * layerbits and authid are filled in on sucess. authid is only
+ * filled in if the client authenticated
+ *
+ */
+int tls_start_servertls(int readfd, int writefd)
+{
+ int sts;
+ int keepalive;
+ SSL_SESSION *session;
+ SSL_CIPHER *cipher;
+
+ if (!tls_serverengine)
+ {
+ /* should never happen */
+ syslog(L_ERROR, "tls_engine not running");
+ return (-1);
+ }
+ if (tls_loglevel >= 1)
+ Printf("setting up TLS connection");
+
+ if (tls_conn == NULL)
+ {
+ tls_conn = (SSL *) SSL_new(CTX);
+ }
+ if (tls_conn == NULL)
+ {
+ return (-1);
+ }
+ SSL_clear(tls_conn);
+
+#if defined(SOL_SOCKET) && defined(SO_KEEPALIVE)
+ /* Set KEEPALIVE to catch broken socket connections. */
+ keepalive = 1;
+ if (setsockopt(readfd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0)
+ syslog(L_ERROR, "fd %d can't setsockopt(KEEPALIVE) %m", readfd);
+ if (setsockopt(writefd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0)
+ syslog(L_ERROR, "fd %d can't setsockopt(KEEPALIVE) %m", writefd);
+#endif /* SOL_SOCKET && SO_KEEPALIVE */
+
+ /* set the file descriptors for SSL to use */
+ if (SSL_set_rfd(tls_conn, readfd)==0)
+ {
+ return (-1);
+ }
+
+ if (SSL_set_wfd(tls_conn, writefd)==0)
+ {
+ return (-1);
+ }
+
+ /*
+ * This is the actual handshake routine. It will do all the negotiations
+ * and will check the client cert etc.
+ */
+ SSL_set_accept_state(tls_conn);
+
+ /*
+ * We do have an SSL_set_fd() and now suddenly a BIO_ routine is called?
+ * Well there is a BIO below the SSL routines that is automatically
+ * created for us, so we can use it for debugging purposes.
+ */
+ if (tls_loglevel >= 3)
+ BIO_set_callback(SSL_get_rbio(tls_conn), bio_dump_cb);
+
+ /* Dump the negotiation for loglevels 3 and 4*/
+ if (tls_loglevel >= 3)
+ do_dump = 1;
+
+ if ((sts = SSL_accept(tls_conn)) <= 0) { /* xxx <= 0 */
+ session = SSL_get_session(tls_conn);
+
+ if (session) {
+ SSL_CTX_remove_session(CTX, session);
+ }
+ if (tls_conn)
+ SSL_free(tls_conn);
+ tls_conn = NULL;
+ return (-1);
+ }
+ /* Only loglevel==4 dumps everything */
+ if (tls_loglevel < 4)
+ do_dump = 0;
+
+ tls_protocol = SSL_get_version(tls_conn);
+ cipher = SSL_get_current_cipher(tls_conn);
+
+ tls_cipher_name = SSL_CIPHER_get_name(cipher);
+ tls_cipher_usebits = SSL_CIPHER_get_bits(cipher,
+ &tls_cipher_algbits);
+ tls_serveractive = 1;
+
+ syslog(L_NOTICE, "starttls: %s with cipher %s (%d/%d bits) no authentication", tls_protocol, tls_cipher_name,
+ tls_cipher_usebits, tls_cipher_algbits);
+
+ return (0);
+}
+
+ssize_t
+SSL_writev (ssl, vector, count)
+ SSL *ssl;
+ const struct iovec *vector;
+ int count;
+{
+ static char *buffer = NULL;
+ static size_t allocsize = 0;
+ char *bp;
+ size_t bytes, to_copy;
+ int i;
+ /* Find the total number of bytes to be written. */
+ bytes = 0;
+ for (i = 0; i < count; ++i)
+ bytes += vector[i].iov_len;
+ /* Allocate a buffer to hold the data. */
+ if (NULL == buffer) {
+ buffer = (char *) xmalloc(bytes);
+ allocsize = bytes;
+ } else if (bytes > allocsize) {
+ buffer = (char *) xrealloc (buffer, bytes);
+ allocsize = bytes;
+ }
+ /* Copy the data into BUFFER. */
+ to_copy = bytes;
+ bp = buffer;
+ for (i = 0; i < count; ++i)
+ {
+#define min(a, b) ((a) > (b) ? (b) : (a))
+ size_t copy = min (vector[i].iov_len, to_copy);
+ memcpy (bp, vector[i].iov_base, copy);
+ bp += copy;
+ to_copy -= copy;
+ if (to_copy == 0)
+ break;
+ }
+ return SSL_write (ssl, buffer, bytes);
+}
+
+
+#endif /* HAVE_SSL */
--- /dev/null
+/* $Id: status.c 7547 2006-08-26 06:18:14Z eagle $
+**
+** Periodic status reporting.
+*/
+#include "config.h"
+#include "clibrary.h"
+#include "portable/socket.h"
+
+#include "inn/innconf.h"
+#include "innd.h"
+#include "innperl.h"
+
+#define MIN_REFRESH 60 /* 1 min */
+#define HTML_STATUS
+#if defined(HTML_STATUS)
+#define STATUS_FILE "inn_status.html" /* will be in pathhttp */
+#else
+#define STATUS_FILE "inn.status" /* will be in pathlog */
+#endif
+
+typedef struct _STATUS {
+ char name[SMBUF];
+ char ip_addr[64];
+ bool can_stream;
+ unsigned short activeCxn;
+ unsigned short sleepingCxns;
+ time_t seconds;
+ unsigned long accepted;
+ unsigned long refused;
+ unsigned long rejected;
+ unsigned long Duplicate;
+ unsigned long Unwanted_u;
+ unsigned long Unwanted_d;
+ unsigned long Unwanted_g;
+ unsigned long Unwanted_s;
+ unsigned long Unwanted_f;
+ float Size;
+ float DuplicateSize;
+ unsigned long Check;
+ unsigned long Check_send;
+ unsigned long Check_deferred;
+ unsigned long Check_got;
+ unsigned long Check_cybercan;
+ unsigned long Takethis;
+ unsigned long Takethis_Ok;
+ unsigned long Takethis_Err;
+ unsigned long Ihave;
+ unsigned long Ihave_Duplicate;
+ unsigned long Ihave_Deferred;
+ unsigned long Ihave_SendIt;
+ unsigned long Ihave_Cybercan;
+ struct _STATUS *next;
+} STATUS;
+
+static unsigned STATUSlast_time;
+char start_time[50];
+
+static unsigned
+STATUSgettime(void)
+{
+ static int init = 0;
+ static struct timeval start_tv;
+ struct timeval tv;
+
+ if (!init) {
+ gettimeofday(&start_tv, NULL);
+ init++;
+ }
+ gettimeofday(&tv, NULL);
+ return((tv.tv_sec - start_tv.tv_sec) * 1000 +
+ (tv.tv_usec - start_tv.tv_usec) / 1000);
+}
+
+void
+STATUSinit(void)
+{
+ time_t now;
+
+ STATUSlast_time = STATUSgettime(); /* First invocation */
+ now = time (NULL) ;
+ strlcpy(start_time, ctime(&now), sizeof(start_time));
+}
+
+static char *
+PrettySize(float size, char *str)
+{
+ if (size > 1073741824) /* 1024*1024*1024 */
+ sprintf (str, "%.1fGb", size / 1073741824.);
+ else
+ if (size > 1048576) /* 1024*1024 */
+ sprintf (str, "%.1fMb", size / 1048576.);
+ else
+ sprintf (str, "%.1fkb", size / 1024.);
+ return (str);
+}
+
+static void
+STATUSsummary(void)
+{
+ FILE *F;
+ int i, j;
+ CHANNEL *cp;
+ int activeCxn = 0;
+ int sleepingCxns = 0;
+ time_t seconds = 0;
+ unsigned long duplicate = 0;
+ unsigned long offered;
+ unsigned long accepted = 0;
+ unsigned long refused = 0;
+ unsigned long rejected = 0;
+ float size = 0;
+ float DuplicateSize = 0;
+ int peers = 0;
+ char TempString[SMBUF];
+ char *path;
+ STATUS *head, *status, *tmp;
+ char str[9];
+ time_t now;
+
+#if defined(HTML_STATUS)
+ path = concatpath(innconf->pathhttp, STATUS_FILE);
+#else
+ path = concatpath(innconf->pathlog, STATUS_FILE);
+#endif
+ if ((F = Fopen(path, "w", TEMPORARYOPEN)) == NULL) {
+ syslog(L_ERROR, "%s cannot open %s: %m", LogName, path);
+ return;
+ }
+
+#if defined(HTML_STATUS)
+ /* HTML Header */
+
+ fprintf (F,"<HTML>\n<HEAD>\n<META HTTP-EQUIV=\"Refresh\" CONTENT=\"%ld;\">\n",
+ innconf->status < MIN_REFRESH ? MIN_REFRESH : innconf->status);
+ fprintf (F, "<TITLE>%s: incoming feeds</TITLE>\n", innconf->pathhost);
+ fprintf (F, "</HEAD>\n<BODY>\n<PRE>\n") ;
+#endif /* defined(HTML_STATUS) */
+
+ fprintf (F, "%s\n", inn_version_string);
+ fprintf (F, "pid %d started %s\n", (int) getpid(), start_time);
+
+ tmp = head = NULL;
+ for (i = 0; (cp = CHANiter(&i, CTnntp)) != NULL; ) {
+ j = 0;
+ strlcpy(TempString,
+ cp->Address.ss_family == 0 ? "localhost" : RChostname(cp),
+ sizeof(TempString));
+ for (status = head ; status != NULL ; status = status->next) {
+ if (strcmp(TempString, status->name) == 0)
+ break;
+ }
+ if (status == NULL) {
+ status = xmalloc(sizeof(STATUS));
+ peers++; /* a new peer */
+ strlcpy(status->name, TempString, sizeof(status->name));
+ strlcpy(status->ip_addr,
+ sprint_sockaddr((struct sockaddr *)&cp->Address),
+ sizeof(status->ip_addr));
+ status->can_stream = cp->Streaming;
+ status->seconds = status->Size = status->DuplicateSize = 0;
+ status->Ihave = status->Ihave_Duplicate =
+ status->Ihave_Deferred = status->Ihave_SendIt =
+ status->Ihave_Cybercan = 0;
+ status->Check = status->Check_send =
+ status->Check_deferred = status->Check_got =
+ status->Check_cybercan = 0;
+ status->Takethis = status->Takethis_Ok = status->Takethis_Err = 0;
+ status->activeCxn = status->sleepingCxns = 0;
+ status->accepted = 0;
+ status->refused = status->rejected = 0;
+ status->Duplicate = status->Unwanted_u = 0;
+ status->Unwanted_d = status->Unwanted_g = 0;
+ status->Unwanted_s = status->Unwanted_f = 0;
+ status->next = NULL;
+ if (head == NULL)
+ head = status;
+ else
+ tmp->next = status;
+ tmp = status;
+ }
+ if (Now.time - cp->Started > status->seconds)
+ status->seconds = Now.time - cp->Started;
+ if (Now.time - cp->Started > seconds)
+ seconds = Now.time - cp->Started;
+ status->accepted += cp->Received;
+ accepted += cp->Received;
+ status->refused += cp->Refused;
+ refused += cp->Refused;
+ status->rejected += cp->Rejected;
+ rejected += cp->Rejected;
+ status->Duplicate += cp->Duplicate;
+ duplicate += cp->Duplicate;
+ status->Unwanted_u += cp->Unwanted_u;
+ status->Unwanted_d += cp->Unwanted_d;
+ status->Unwanted_g += cp->Unwanted_g;
+ status->Unwanted_s += cp->Unwanted_s;
+ status->Unwanted_f += cp->Unwanted_f;
+ status->Ihave += cp->Ihave;
+ status->Ihave_Duplicate += cp->Ihave_Duplicate;
+ status->Ihave_Deferred += cp->Ihave_Deferred;
+ status->Ihave_SendIt += cp->Ihave_SendIt;
+ status->Ihave_Cybercan += cp->Ihave_Cybercan;
+ status->Check += cp->Check;
+ status->Check_send += cp->Check_send;
+ status->Check_deferred += cp->Check_deferred;
+ status->Check_got += cp->Check_got;
+ status->Check_cybercan += cp->Check_cybercan;
+ status->Takethis += cp->Takethis;
+ status->Takethis_Ok += cp->Takethis_Ok;
+ status->Takethis_Err += cp->Takethis_Err;
+ status->Size += cp->Size;
+ status->DuplicateSize += cp->DuplicateSize;
+ size += cp->Size;
+ DuplicateSize += cp->DuplicateSize;
+ if (CHANsleeping(cp)) {
+ sleepingCxns++;
+ status->sleepingCxns++;
+ } else {
+ activeCxn++;
+ status->activeCxn++;
+ }
+ }
+
+ /* Header */
+ now = time (NULL);
+ strlcpy (TempString, ctime (&now), sizeof(TempString));
+ fprintf (F, "Updated: %s", TempString);
+ fprintf (F, "(peers: %d, active-cxns: %d, sleeping-cxns: %d)\n\n",
+ peers, activeCxn, sleepingCxns);
+
+ fprintf (F, "Mode: %s", Mode == OMrunning ? "running" :
+ Mode == OMpaused ? "paused" :
+ Mode == OMthrottled ? "throttled" : "Unknown");
+ if ((Mode == OMpaused) || (Mode == OMthrottled))
+ fprintf (F, " (%s)", ModeReason);
+
+ /* Global configuration */
+ fprintf (F, "\n\nConfiguration file: %s\n\n", _PATH_CONFIG);
+
+ fprintf (F, "Global configuration parameters:\n");
+ fprintf (F, " Largest Article: %ld bytes\n", innconf->maxartsize);
+ fprintf (F, " Max Incoming connections: ");
+ if (innconf->maxconnections)
+ fprintf (F, "%ld\n", innconf->maxconnections);
+ else
+ fprintf (F, "unlimited\n");
+ fprintf (F, " Max Outgoing file feeds: %d\n", MaxOutgoing);
+ fprintf (F, " Cutoff: ");
+ if (innconf->artcutoff)
+ fprintf (F, "%ld days\n", innconf->artcutoff);
+ else
+ fprintf (F, "none\n");
+ fprintf (F, " Timeout period: %ld seconds\n",
+ (long)TimeOut.tv_sec);
+ if (innconf->remembertrash) {
+ fprintf (F, " Remember Trash: Yes\n");
+ } else {
+ fprintf (F, " Remember Trash: No\n");
+ }
+#if defined(DO_TCL)
+ fprintf (F, " Tcl filtering: %s\n",
+ TCLFilterActive ? "enabled" : "disabled");
+#endif /* defined(DO_TCL) */
+#if defined(DO_PERL)
+ fprintf (F, " Perl filtering: %s\n",
+ PerlFilterActive ? "enabled" : "disabled");
+#endif /* defined(DO_PERL) */
+
+ fputc ('\n', F) ;
+
+ /* Global values */
+ fprintf (F, "global (process)\n");
+ fprintf (F, " seconds: %ld\n", (long) seconds);
+ offered = accepted + refused + rejected;
+ fprintf (F, " offered: %-9ld\n", offered);
+ if (!offered) offered = 1; /* to avoid division by zero */
+ if (!size) size = 1; /* avoid divide by zero here too */
+ fprintf (F, " accepted: %-9ld %%accepted: %.1f%%\n",
+ accepted, (float) accepted / offered * 100);
+ fprintf (F, " refused: %-9ld %%refused: %.1f%%\n",
+ refused, (float) refused / offered * 100);
+ fprintf (F, " rejected: %-9ld %%rejected: %.1f%%\n",
+ rejected, (float) rejected / offered * 100);
+ fprintf (F, " duplicated: %-9ld %%duplicated: %.1f%%\n",
+ duplicate, (float) duplicate / offered * 100);
+ fprintf (F, " bytes: %-7s\n", PrettySize (size + DuplicateSize, str));
+ fprintf (F, " duplicated size: %-7s %%duplicated size: %.1f%%\n",
+ PrettySize(DuplicateSize, str), (float) DuplicateSize / size * 100);
+ fputc ('\n', F) ;
+
+ /* Incoming Feeds */
+ for (status = head ; status != NULL ;) {
+ fprintf (F, "%s\n", status->name);
+ fprintf (F, " seconds: %-7ld ", (long) status->seconds);
+ fprintf (F, " duplicates: %-7ld ", status->Duplicate);
+ fprintf (F, " ip address: %s\n", status->ip_addr);
+ fprintf (F, " offered: %-7ld ",
+ status->accepted + status->refused + status->rejected);
+ fprintf (F, " uw newsgroups: %-7ld ", status->Unwanted_g);
+ fprintf (F, " active cxns: %d\n", status->activeCxn);
+ fprintf (F, " accepted: %-7ld ", status->accepted);
+ fprintf (F, "uw distributions: %-7ld ", status->Unwanted_d);
+ fprintf (F, " sleeping cxns: %d\n", status->sleepingCxns);
+ fprintf (F, " refused: %-7ld ", status->refused);
+ fprintf (F, " unapproved: %-7ld ", status->Unwanted_u);
+ fprintf (F, "want streaming: %s\n",
+ status->can_stream ? "Yes" : "No");
+ fprintf (F, " rejected: %-7ld ", status->rejected);
+ fprintf (F, " filtered: %-7ld ", status->Unwanted_f);
+ fprintf (F, " is streaming: %s\n",
+ (status->Check || status->Takethis) ? "Yes" : "No");
+ fprintf (F, " size: %-8s ", PrettySize(status->Size, str));
+ fprintf (F, " bad sites: %-7ld ", status->Unwanted_s);
+ fprintf (F, "duplicate size: %s\n", PrettySize(status->DuplicateSize, str));
+ fprintf (F, " Protocol:\n");
+ fprintf (F, " Ihave: %-6ld SendIt[%d]: %-6ld Got[%d]: %-6ld Deferred[%d]: %ld\n",
+ status->Ihave, NNTP_SENDIT_VAL, status->Ihave_SendIt,
+ NNTP_HAVEIT_VAL, status->Ihave_Duplicate, NNTP_RESENDIT_VAL,
+ status->Ihave_Deferred);
+ fprintf (F, " Check: %-6ld SendIt[%d]: %-6ld Got[%d]: %-6ld Deferred[%d]: %ld\n",
+ status->Check, NNTP_OK_SENDID_VAL, status->Check_send,
+ NNTP_ERR_GOTID_VAL, status->Check_got, NNTP_RESENDID_VAL,
+ status->Check_deferred);
+ fprintf (F, " Takethis: %-6ld Ok[%d]: %-6ld Error[%d]: %-6ld\n",
+ status->Takethis, NNTP_OK_RECID_VAL, status->Takethis_Ok,
+ NNTP_ERR_FAILID_VAL, status->Takethis_Err);
+ if (innconf->refusecybercancels) {
+ fprintf (F, " Cancelrejects: Ihave[%d]: %-6ld Check[%d]: %-6ld\n",
+ NNTP_HAVEIT_VAL, status->Ihave_Cybercan,
+ NNTP_ERR_GOTID_VAL, status->Check_cybercan);
+ }
+ fputc ('\n', F) ;
+ tmp = status->next;
+ free(status);
+ status = tmp;
+ }
+
+#if defined(HTML_STATUS)
+ /* HTML Footer */
+ fprintf (F,"</PRE>\n</BODY>\n</HTML>\n");
+#endif /* defined(HTML_STATUS) */
+
+ Fclose(F);
+}
+
+void
+STATUSmainloophook(void)
+{
+ unsigned now;
+
+ if (!innconf->status)
+ return;
+ now = STATUSgettime();
+
+ if (now - STATUSlast_time > (unsigned)(innconf->status * 1000)) {
+ STATUSsummary();
+ STATUSlast_time = now;
+ }
+}
--- /dev/null
+/* $Id: misc.c 6535 2003-12-10 09:02:22Z rra $
+**
+** Miscellaneous support routines.
+*/
+
+#include "config.h"
+#include "clibrary.h"
+
+/* Needed on AIX 4.1 to get fd_set and friends. */
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+
+#include "inn/innconf.h"
+#include "nnrpd.h"
+#include "tls.h"
+#include "sasl_config.h"
+
+#ifdef HAVE_SSL
+extern SSL *tls_conn;
+extern int nnrpd_starttls_done;
+#endif
+
+
+/*
+** Parse a string into a NULL-terminated array of words; return number
+** of words. If argvp isn't NULL, it and what it points to will be freed.
+*/
+int
+Argify(line, argvp)
+ char *line;
+ char ***argvp;
+{
+ char **argv;
+ char *p;
+
+ if (*argvp != NULL) {
+ free(*argvp[0]);
+ free(*argvp);
+ }
+
+ /* Copy the line, which we will split up. */
+ while (ISWHITE(*line))
+ line++;
+ p = xstrdup(line);
+
+ /* Allocate worst-case amount of space. */
+ for (*argvp = argv = xmalloc((strlen(p) + 2) * sizeof(char *)); *p; ) {
+ /* Mark start of this word, find its end. */
+ for (*argv++ = p; *p && !ISWHITE(*p); )
+ p++;
+ if (*p == '\0')
+ break;
+
+ /* Nip off word, skip whitespace. */
+ for (*p++ = '\0'; ISWHITE(*p); )
+ p++;
+ }
+ *argv = NULL;
+ return argv - *argvp;
+}
+
+
+/*
+** Take a vector which Argify made and glue it back together with
+** spaces between each element. Returns a pointer to dynamic space.
+*/
+char *
+Glom(av)
+ char **av;
+{
+ char **v;
+ int i;
+ char *save;
+
+ /* Get space. */
+ for (i = 0, v = av; *v; v++)
+ i += strlen(*v) + 1;
+ i++;
+
+ save = xmalloc(i);
+ save[0] = '\0';
+ for (v = av; *v; v++) {
+ if (v > av)
+ strlcat(save, " ", i);
+ strlcat(save, *v, i);
+ }
+
+ return save;
+}
+
+
+/*
+** Match a list of newsgroup specifiers against a list of newsgroups.
+** func is called to see if there is a match.
+*/
+bool PERMmatch(char **Pats, char **list)
+{
+ int i;
+ char *p;
+ int match = false;
+
+ if (Pats == NULL || Pats[0] == NULL)
+ return true;
+
+ for ( ; *list; list++) {
+ for (i = 0; (p = Pats[i]) != NULL; i++) {
+ if (p[0] == '!') {
+ if (uwildmat(*list, ++p))
+ match = false;
+ }
+ else if (uwildmat(*list, p))
+ match = true;
+ }
+ if (match)
+ /* If we can read it in one group, we can read it, period. */
+ return true;
+ }
+
+ return false;
+}
+
+
+/*
+** Check to see if user is allowed to see this article by matching
+** Newsgroups line.
+*/
+bool
+PERMartok(void)
+{
+ static char **grplist;
+ char *p, **grp;
+
+ if (!PERMspecified)
+ return false;
+
+ if ((p = GetHeader("Xref")) == NULL) {
+ /* in case article does not include Xref */
+ if ((p = GetHeader("Newsgroups")) != NULL) {
+ if (!NGgetlist(&grplist, p))
+ /* No newgroups or null entry. */
+ return true;
+ } else {
+ return true;
+ }
+ } else {
+ /* skip path element */
+ if ((p = strchr(p, ' ')) == NULL)
+ return true;
+ for (p++ ; *p == ' ' ; p++);
+ if (*p == '\0')
+ return true;
+ if (!NGgetlist(&grplist, p))
+ /* No newgroups or null entry. */
+ return true;
+ /* chop ':' and article number */
+ for (grp = grplist ; *grp != NULL ; grp++) {
+ if ((p = strchr(*grp, ':')) == NULL)
+ return true;
+ *p = '\0';
+ }
+ }
+
+#ifdef DO_PYTHON
+ if (PY_use_dynamic) {
+ char *reply;
+
+ /* Authorize user at a Python authorization module */
+ if (PY_dynamic(PERMuser, p, false, &reply) < 0) {
+ syslog(L_NOTICE, "PY_dynamic(): authorization skipped due to no Python dynamic method defined.");
+ } else {
+ if (reply != NULL) {
+ syslog(L_TRACE, "PY_dynamic() returned a refuse string for user %s at %s who wants to read %s: %s", PERMuser, ClientHost, p, reply);
+ free(reply);
+ return false;
+ }
+ return true;
+ }
+ }
+#endif /* DO_PYTHON */
+
+ return PERMmatch(PERMreadlist, grplist);
+}
+
+
+/*
+** Parse a newsgroups line, return true if there were any.
+*/
+bool
+NGgetlist(argvp, list)
+ char ***argvp;
+ char *list;
+{
+ char *p;
+
+ for (p = list; *p; p++)
+ if (*p == ',')
+ *p = ' ';
+
+ return Argify(list, argvp) != 0;
+}
+
+
+/*********************************************************************
+ * POSTING RATE LIMITS - The following code implements posting rate
+ * limits. News clients are indexed by IP number (or PERMuser, see
+ * config file). After a relatively configurable number of posts, the nnrpd
+ * process will sleep for a period of time before posting anything.
+ *
+ * Each time that IP number posts a message, the time of
+ * posting and the previous sleep time is stored. The new sleep time
+ * is computed based on these values.
+ *
+ * To compute the new sleep time, the previous sleep time is, for most
+ * cases multiplied by a factor (backoff_k).
+ *
+ * See inn.conf(5) for how this code works
+ *
+ *********************************************************************/
+
+/* Defaults are pass through, i.e. not enabled
+ * NEW for INN 1.8 - Use the inn.conf file to specify the following:
+ *
+ * backoff_k: <integer>
+ * backoff_postfast: <integer>
+ * backoff_postslow: <integer>
+ * backoff_trigger: <integer>
+ * backoff_db: <path>
+ * backoff_auth: <on|off>
+ *
+ * You may also specify posting backoffs on a per user basis. To do this
+ * turn on "backoff_auth"
+ *
+ * Now these are runtime constants. <grin>
+ */
+static char postrec_dir[SMBUF]; /* Where is the post record directory? */
+
+void
+InitBackoffConstants()
+{
+ struct stat st;
+
+ /* Default is not to enable this code */
+ BACKOFFenabled = false;
+
+ /* Read the runtime config file to get parameters */
+
+ if ((PERMaccessconf->backoff_db == NULL) ||
+ !(PERMaccessconf->backoff_k >= 0L && PERMaccessconf->backoff_postfast >= 0L && PERMaccessconf->backoff_postslow >= 1L))
+ return;
+
+ /* Need this database for backing off */
+ strlcpy(postrec_dir, PERMaccessconf->backoff_db, sizeof(postrec_dir));
+ if (stat(postrec_dir, &st) < 0) {
+ if (ENOENT == errno) {
+ if (!MakeDirectory(postrec_dir, true)) {
+ syslog(L_ERROR, "%s cannot create backoff_db '%s': %s",ClientHost,postrec_dir,strerror(errno));
+ return;
+ }
+ } else {
+ syslog(L_ERROR, "%s cannot stat backoff_db '%s': %s",ClientHost,postrec_dir,strerror(errno));
+ return;
+ }
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ syslog(L_ERROR, "%s backoff_db '%s' is not a directory",ClientHost,postrec_dir);
+ return;
+ }
+
+ BACKOFFenabled = true;
+
+ return;
+}
+
+/*
+ * PostRecs are stored in individual files. I didn't have a better
+ * way offhand, don't want to touch DBZ, and the number of posters is
+ * small compared to the number of readers. This is the filename corresponding
+ * to an IP number.
+ */
+char
+*PostRecFilename(ip,user)
+ char *ip;
+ char *user;
+{
+ static char buff[SPOOLNAMEBUFF];
+ char dirbuff[SPOOLNAMEBUFF];
+ struct in_addr inaddr;
+ unsigned long int addr;
+ unsigned char quads[4];
+ unsigned int i;
+
+ if (PERMaccessconf->backoff_auth) {
+ snprintf(buff, sizeof(buff), "%s/%s", postrec_dir, user);
+ return(buff);
+ }
+
+ if (inet_aton(ip, &inaddr) < 1) {
+ /* If inet_aton() fails, we'll assume it's an IPv6 address. We'll
+ * also assume for now that we're dealing with a limited number of
+ * IPv6 clients so we'll place their files all in the same
+ * directory for simplicity. Someday we'll need to change this to
+ * something more scalable such as DBZ when IPv6 clients become
+ * more popular. */
+ snprintf(buff, sizeof(buff), "%s/%s", postrec_dir, ip);
+ return(buff);
+ }
+ /* If it's an IPv4 address just fall through. */
+
+ addr = ntohl(inaddr.s_addr);
+ for (i=0; i<4; i++)
+ quads[i] = (unsigned char) (0xff & (addr>>(i*8)));
+
+ snprintf(dirbuff, sizeof(dirbuff), "%s/%03d%03d/%03d",
+ postrec_dir, quads[3], quads[2], quads[1]);
+ if (!MakeDirectory(dirbuff,true)) {
+ syslog(L_ERROR, "%s Unable to create postrec directories '%s': %s",
+ ClientHost, dirbuff, strerror(errno));
+ return NULL;
+ }
+ snprintf(buff, sizeof(buff), "%s/%03d", dirbuff, quads[0]);
+ return(buff);
+}
+
+/*
+ * Lock the post rec file. Return 1 on lock, 0 on error
+ */
+int
+LockPostRec(path)
+ char *path;
+{
+ char lockname[SPOOLNAMEBUFF];
+ char temp[SPOOLNAMEBUFF];
+ int statfailed = 0;
+
+ snprintf(lockname, sizeof(lockname), "%s.lock", path);
+
+ for (;; sleep(5)) {
+ int fd;
+ struct stat st;
+ time_t now;
+
+ fd = open(lockname, O_WRONLY|O_EXCL|O_CREAT, 0600);
+ if (fd >= 0) {
+ /* We got the lock! */
+ snprintf(temp, sizeof(temp), "pid:%ld\n", (unsigned long) getpid());
+ write(fd, temp, strlen(temp));
+ close(fd);
+ return(1);
+ }
+
+ /* No lock. See if the file is there. */
+ if (stat(lockname, &st) < 0) {
+ syslog(L_ERROR, "%s cannot stat lock file %s", ClientHost, strerror(errno));
+ if (statfailed++ > 5) return(0);
+ continue;
+ }
+
+ /* If lockfile is older than the value of
+ PERMaccessconf->backoff_postslow, remove it */
+ statfailed = 0;
+ time(&now);
+ if (now < st.st_ctime + PERMaccessconf->backoff_postslow) continue;
+ syslog(L_ERROR, "%s removing stale lock file %s", ClientHost, lockname);
+ unlink(lockname);
+ }
+}
+
+void
+UnlockPostRec(path)
+ char *path;
+{
+ char lockname[SPOOLNAMEBUFF];
+
+ snprintf(lockname, sizeof(lockname), "%s.lock", path);
+ if (unlink(lockname) < 0) {
+ syslog(L_ERROR, "%s can't unlink lock file: %s", ClientHost,strerror(errno)) ;
+ }
+ return;
+}
+
+/*
+ * Get the stored postrecord for that IP
+ */
+static int
+GetPostRecord(char *path, long *lastpost, long *lastsleep, long *lastn)
+{
+ static char buff[SMBUF];
+ FILE *fp;
+ char *s;
+
+ fp = fopen(path,"r");
+ if (fp == NULL) {
+ if (errno == ENOENT) {
+ return 1;
+ }
+ syslog(L_ERROR, "%s Error opening '%s': %s",
+ ClientHost, path, strerror(errno));
+ return 0;
+ }
+
+ if (fgets(buff,SMBUF,fp) == NULL) {
+ syslog(L_ERROR, "%s Error reading '%s': %s",
+ ClientHost, path, strerror(errno));
+ return 0;
+ }
+ *lastpost = atol(buff);
+
+ if ((s = strchr(buff,',')) == NULL) {
+ syslog(L_ERROR, "%s bad data in postrec file: '%s'",
+ ClientHost, buff);
+ return 0;
+ }
+ s++; *lastsleep = atol(s);
+
+ if ((s = strchr(s,',')) == NULL) {
+ syslog(L_ERROR, "%s bad data in postrec file: '%s'",
+ ClientHost, buff);
+ return 0;
+ }
+ s++; *lastn = atol(s);
+
+ fclose(fp);
+ return 1;
+}
+
+/*
+ * Store the postrecord for that IP
+ */
+static int
+StorePostRecord(char *path, time_t lastpost, long lastsleep, long lastn)
+{
+ FILE *fp;
+
+ fp = fopen(path,"w");
+ if (fp == NULL) {
+ syslog(L_ERROR, "%s Error opening '%s': %s",
+ ClientHost, path, strerror(errno));
+ return 0;
+ }
+
+ fprintf(fp,"%ld,%ld,%ld\n",(long) lastpost,lastsleep,lastn);
+ fclose(fp);
+ return 1;
+}
+
+/*
+ * Return the proper sleeptime. Return false on error.
+ */
+int
+RateLimit(sleeptime,path)
+ long *sleeptime;
+ char *path;
+{
+ TIMEINFO Now;
+ long prevpost,prevsleep,prevn,n;
+
+ if (GetTimeInfo(&Now) < 0)
+ return 0;
+
+ prevpost = 0L; prevsleep = 0L; prevn = 0L; n = 0L;
+ if (!GetPostRecord(path,&prevpost,&prevsleep,&prevn)) {
+ syslog(L_ERROR, "%s can't get post record: %s",
+ ClientHost, strerror(errno));
+ return 0;
+ }
+ /*
+ * Just because yer paranoid doesn't mean they ain't out ta get ya
+ * This is called paranoid clipping
+ */
+ if (prevn < 0L) prevn = 0L;
+ if (prevsleep < 0L) prevsleep = 0L;
+ if (prevsleep > PERMaccessconf->backoff_postfast) prevsleep = PERMaccessconf->backoff_postfast;
+
+ /*
+ * Compute the new sleep time
+ */
+ *sleeptime = 0L;
+ if (prevpost <= 0L) {
+ prevpost = 0L;
+ prevn = 1L;
+ } else {
+ n = Now.time - prevpost;
+ if (n < 0L) {
+ syslog(L_NOTICE,"%s previous post was in the future (%ld sec)",
+ ClientHost,n);
+ n = 0L;
+ }
+ if (n < PERMaccessconf->backoff_postfast) {
+ if (prevn >= PERMaccessconf->backoff_trigger) {
+ *sleeptime = 1 + (prevsleep * PERMaccessconf->backoff_k);
+ }
+ } else if (n < PERMaccessconf->backoff_postslow) {
+ if (prevn >= PERMaccessconf->backoff_trigger) {
+ *sleeptime = prevsleep;
+ }
+ } else {
+ prevn = 0L;
+ }
+ prevn++;
+ }
+
+ *sleeptime = ((*sleeptime) > PERMaccessconf->backoff_postfast) ? PERMaccessconf->backoff_postfast : (*sleeptime);
+ /* This ought to trap this bogon */
+ if ((*sleeptime) < 0L) {
+ syslog(L_ERROR,"%s Negative sleeptime detected: %ld, prevsleep: %ld, N: %ld",ClientHost,*sleeptime,prevsleep,n);
+ *sleeptime = 0L;
+ }
+
+ /* Store the postrecord */
+ if (!StorePostRecord(path,Now.time,*sleeptime,prevn)) {
+ syslog(L_ERROR, "%s can't store post record: %s", ClientHost, strerror(errno));
+ return 0;
+ }
+
+ return 1;
+}
+
+#ifdef HAVE_SSL
+/*
+** The "STARTTLS" command. RFC2595.
+*/
+/* ARGSUSED0 */
+
+void
+CMDstarttls(ac, av)
+ int ac UNUSED;
+ char *av[] UNUSED;
+{
+ int result;
+
+ tls_init();
+ if (nnrpd_starttls_done == 1) {
+ Reply("%d Already successfully executed STARTTLS\r\n",
+ NNTP_STARTTLS_DONE_VAL);
+ return;
+ }
+
+ Reply("%d Begin TLS negotiation now\r\n", NNTP_STARTTLS_NEXT_VAL);
+ fflush(stdout);
+
+ /* must flush our buffers before starting tls */
+
+ result=tls_start_servertls(0, /* read */
+ 1); /* write */
+ if (result==-1) {
+ Reply("%d Starttls failed\r\n", NNTP_STARTTLS_BAD_VAL);
+ return;
+ }
+ nnrpd_starttls_done = 1;
+}
+#endif /* HAVE_SSL */
--- /dev/null
+/* $Id: article.c 7538 2006-08-26 05:44:06Z eagle $
+**
+** Article-related routines.
+*/
+
+#include "config.h"
+#include "clibrary.h"
+#include <assert.h>
+#if HAVE_LIMITS_H
+# include <limits.h>
+#endif
+#include <sys/uio.h>
+
+#include "inn/innconf.h"
+#include "inn/messages.h"
+#include "inn/wire.h"
+#include "nnrpd.h"
+#include "ov.h"
+#include "tls.h"
+#include "cache.h"
+
+#ifdef HAVE_SSL
+extern SSL *tls_conn;
+#endif
+
+/*
+** Data structures for use in ARTICLE/HEAD/BODY/STAT common code.
+*/
+typedef enum _SENDTYPE {
+ STarticle,
+ SThead,
+ STbody,
+ STstat
+} SENDTYPE;
+
+typedef struct _SENDDATA {
+ SENDTYPE Type;
+ int ReplyCode;
+ const char *Item;
+} SENDDATA;
+
+static char ARTnotingroup[] = NNTP_NOTINGROUP;
+static char ARTnoartingroup[] = NNTP_NOARTINGRP;
+static char ARTnocurrart[] = NNTP_NOCURRART;
+static ARTHANDLE *ARThandle = NULL;
+static SENDDATA SENDbody = {
+ STbody, NNTP_BODY_FOLLOWS_VAL, "body"
+};
+static SENDDATA SENDarticle = {
+ STarticle, NNTP_ARTICLE_FOLLOWS_VAL, "article"
+};
+static SENDDATA SENDstat = {
+ STstat, NNTP_NOTHING_FOLLOWS_VAL, "status"
+};
+static SENDDATA SENDhead = {
+ SThead, NNTP_HEAD_FOLLOWS_VAL, "head"
+};
+
+
+static struct iovec iov[IOV_MAX > 1024 ? 1024 : IOV_MAX];
+static int queued_iov = 0;
+
+static void PushIOvHelper(struct iovec* vec, int* countp) {
+ int result;
+ TMRstart(TMR_NNTPWRITE);
+#ifdef HAVE_SSL
+ if (tls_conn) {
+Again:
+ result = SSL_writev(tls_conn, vec, *countp);
+ switch (SSL_get_error(tls_conn, result)) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_SYSCALL:
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ goto Again;
+ break;
+ case SSL_ERROR_SSL:
+ SSL_shutdown(tls_conn);
+ tls_conn = NULL;
+ errno = ECONNRESET;
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ break;
+ }
+ } else {
+ result = xwritev(STDOUT_FILENO, vec, *countp);
+ }
+#else
+ result = xwritev(STDOUT_FILENO, vec, *countp);
+#endif
+ TMRstop(TMR_NNTPWRITE);
+ if (result == -1) {
+ /* we can't recover, since we can't resynchronise with our
+ * peer */
+ ExitWithStats(1, true);
+ }
+ *countp = 0;
+}
+
+static void
+PushIOvRateLimited(void) {
+ double start, end, elapsed, target;
+ struct iovec newiov[IOV_MAX > 1024 ? 1024 : IOV_MAX];
+ int newiov_len;
+ int sentiov;
+ int i;
+ int bytesfound;
+ int chunkbittenoff;
+ struct timeval waittime;
+
+ while (queued_iov) {
+ bytesfound = newiov_len = 0;
+ sentiov = 0;
+ for (i = 0; (i < queued_iov) && (bytesfound < MaxBytesPerSecond); i++) {
+ if ((signed)iov[i].iov_len + bytesfound > MaxBytesPerSecond) {
+ chunkbittenoff = MaxBytesPerSecond - bytesfound;
+ newiov[newiov_len].iov_base = iov[i].iov_base;
+ newiov[newiov_len++].iov_len = chunkbittenoff;
+ iov[i].iov_base = (char *)iov[i].iov_base + chunkbittenoff;
+ iov[i].iov_len -= chunkbittenoff;
+ bytesfound += chunkbittenoff;
+ } else {
+ newiov[newiov_len++] = iov[i];
+ sentiov++;
+ bytesfound += iov[i].iov_len;
+ }
+ }
+ assert(sentiov <= queued_iov);
+ start = TMRnow_double();
+ PushIOvHelper(newiov, &newiov_len);
+ end = TMRnow_double();
+ target = (double) bytesfound / MaxBytesPerSecond;
+ elapsed = end - start;
+ if (elapsed < 1 && elapsed < target) {
+ waittime.tv_sec = 0;
+ waittime.tv_usec = (target - elapsed) * 1e6;
+ start = TMRnow_double();
+ if (select(0, NULL, NULL, NULL, &waittime) != 0)
+ syswarn("%s: select in PushIOvRateLimit failed", ClientHost);
+ end = TMRnow_double();
+ IDLEtime += end - start;
+ }
+ memmove(iov, &iov[sentiov], (queued_iov - sentiov) * sizeof(struct iovec));
+ queued_iov -= sentiov;
+ }
+}
+
+static void
+PushIOv(void) {
+ TMRstart(TMR_NNTPWRITE);
+ fflush(stdout);
+ TMRstop(TMR_NNTPWRITE);
+ if (MaxBytesPerSecond != 0)
+ PushIOvRateLimited();
+ else
+ PushIOvHelper(iov, &queued_iov);
+}
+
+static void
+SendIOv(const char *p, int len) {
+ char *q;
+
+ if (queued_iov) {
+ q = (char *)iov[queued_iov - 1].iov_base + iov[queued_iov - 1].iov_len;
+ if (p == q) {
+ iov[queued_iov - 1].iov_len += len;
+ return;
+ }
+ }
+ iov[queued_iov].iov_base = (char*)p;
+ iov[queued_iov++].iov_len = len;
+ if (queued_iov == IOV_MAX)
+ PushIOv();
+}
+
+static char *_IO_buffer_ = NULL;
+static int highwater = 0;
+
+static void
+PushIOb(void) {
+ TMRstart(TMR_NNTPWRITE);
+ fflush(stdout);
+#ifdef HAVE_SSL
+ if (tls_conn) {
+ int r;
+Again:
+ r = SSL_write(tls_conn, _IO_buffer_, highwater);
+ switch (SSL_get_error(tls_conn, r)) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_SYSCALL:
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ goto Again;
+ break;
+ case SSL_ERROR_SSL:
+ SSL_shutdown(tls_conn);
+ tls_conn = NULL;
+ errno = ECONNRESET;
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ break;
+ }
+ if (r != highwater) {
+ TMRstop(TMR_NNTPWRITE);
+ highwater = 0;
+ return;
+ }
+ } else {
+ if (xwrite(STDOUT_FILENO, _IO_buffer_, highwater) != highwater) {
+ TMRstop(TMR_NNTPWRITE);
+ highwater = 0;
+ return;
+ }
+ }
+#else
+ if (xwrite(STDOUT_FILENO, _IO_buffer_, highwater) != highwater) {
+ TMRstop(TMR_NNTPWRITE);
+ highwater = 0;
+ return;
+ }
+#endif
+ TMRstop(TMR_NNTPWRITE);
+ highwater = 0;
+}
+
+static void
+SendIOb(const char *p, int len) {
+ int tocopy;
+
+ if (_IO_buffer_ == NULL)
+ _IO_buffer_ = xmalloc(BIG_BUFFER);
+
+ while (len > 0) {
+ tocopy = (len > (BIG_BUFFER - highwater)) ? (BIG_BUFFER - highwater) : len;
+ memcpy(&_IO_buffer_[highwater], p, tocopy);
+ p += tocopy;
+ highwater += tocopy;
+ len -= tocopy;
+ if (highwater == BIG_BUFFER)
+ PushIOb();
+ }
+}
+
+
+/*
+** If we have an article open, close it.
+*/
+void ARTclose(void)
+{
+ if (ARThandle) {
+ SMfreearticle(ARThandle);
+ ARThandle = NULL;
+ }
+}
+
+bool ARTinstorebytoken(TOKEN token)
+{
+ ARTHANDLE *art;
+ struct timeval stv, etv;
+
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&stv, NULL);
+ }
+ art = SMretrieve(token, RETR_STAT); /* XXX This isn't really overstats, is it? */
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&etv, NULL);
+ OVERartcheck+=(etv.tv_sec - stv.tv_sec) * 1000;
+ OVERartcheck+=(etv.tv_usec - stv.tv_usec) / 1000;
+ }
+ if (art) {
+ SMfreearticle(art);
+ return true;
+ }
+ return false;
+}
+
+/*
+** If the article name is valid, open it and stuff in the ID.
+*/
+static bool ARTopen(ARTNUM artnum)
+{
+ static ARTNUM save_artnum;
+ TOKEN token;
+
+ /* Re-use article if it's the same one. */
+ if (save_artnum == artnum) {
+ if (ARThandle)
+ return true;
+ }
+ ARTclose();
+
+ if (!OVgetartinfo(GRPcur, artnum, &token))
+ return false;
+
+ TMRstart(TMR_READART);
+ ARThandle = SMretrieve(token, RETR_ALL);
+ TMRstop(TMR_READART);
+ if (ARThandle == NULL) {
+ return false;
+ }
+
+ save_artnum = artnum;
+ return true;
+}
+
+
+/*
+** Open the article for a given Message-ID.
+*/
+static bool
+ARTopenbyid(char *msg_id, ARTNUM *ap, bool final)
+{
+ TOKEN token;
+
+ *ap = 0;
+ token = cache_get(HashMessageID(msg_id), final);
+ if (token.type == TOKEN_EMPTY) {
+ if (History == NULL) {
+ time_t statinterval;
+
+ /* Do lazy opens of the history file - lots of clients
+ * will never ask for anything by message id, so put off
+ * doing the work until we have to */
+ History = HISopen(HISTORY, innconf->hismethod, HIS_RDONLY);
+ if (!History) {
+ syslog(L_NOTICE, "cant initialize history");
+ Reply("%d NNTP server unavailable. Try later.\r\n",
+ NNTP_TEMPERR_VAL);
+ ExitWithStats(1, true);
+ }
+ statinterval = 30;
+ HISctl(History, HISCTLS_STATINTERVAL, &statinterval);
+ }
+ if (!HISlookup(History, msg_id, NULL, NULL, NULL, &token))
+ return false;
+ }
+ if (token.type == TOKEN_EMPTY)
+ return false;
+ TMRstart(TMR_READART);
+ ARThandle = SMretrieve(token, RETR_ALL);
+ TMRstop(TMR_READART);
+ if (ARThandle == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+/*
+** Send a (part of) a file to stdout, doing newline and dot conversion.
+*/
+static void ARTsendmmap(SENDTYPE what)
+{
+ const char *p, *q, *r;
+ const char *s, *path, *xref, *endofpath;
+ long bytecount;
+ char lastchar;
+
+ ARTcount++;
+ GRParticles++;
+ bytecount = 0;
+ lastchar = -1;
+
+ /* Get the headers and detect if wire format. */
+ if (what == STarticle) {
+ q = ARThandle->data;
+ p = ARThandle->data + ARThandle->len;
+ } else {
+ for (q = p = ARThandle->data; p < (ARThandle->data + ARThandle->len); p++) {
+ if (*p == '\r')
+ continue;
+ if (*p == '\n') {
+ if (lastchar == '\n') {
+ if (what == SThead) {
+ if (*(p-1) == '\r')
+ p--;
+ break;
+ } else {
+ q = p + 1;
+ p = ARThandle->data + ARThandle->len;
+ break;
+ }
+ }
+ }
+ lastchar = *p;
+ }
+ }
+
+ /* q points to the start of the article buffer, p to the end of it */
+ if (VirtualPathlen > 0 && (what != STbody)) {
+ path = wire_findheader(ARThandle->data, ARThandle->len, "Path");
+ if (path == NULL) {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ PushIOv();
+ ARTget++;
+ return;
+ } else {
+ xref = wire_findheader(ARThandle->data, ARThandle->len, "Xref");
+ if (xref == NULL) {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ PushIOv();
+ ARTget++;
+ return;
+ }
+ }
+ endofpath = wire_endheader(path, ARThandle->data + ARThandle->len - 1);
+ if (endofpath == NULL) {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ PushIOv();
+ ARTget++;
+ return;
+ }
+ if ((r = memchr(xref, ' ', p - xref)) == NULL || r == p) {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ PushIOv();
+ ARTget++;
+ return;
+ }
+ /* r points to the first space in the Xref header */
+ for (s = path, lastchar = '\0';
+ s + VirtualPathlen + 1 < endofpath;
+ lastchar = *s++) {
+ if ((lastchar != '\0' && lastchar != '!') || *s != *VirtualPath ||
+ strncmp(s, VirtualPath, VirtualPathlen - 1) != 0)
+ continue;
+ if (*(s + VirtualPathlen - 1) != '\0' &&
+ *(s + VirtualPathlen - 1) != '!')
+ continue;
+ break;
+ }
+ if (s + VirtualPathlen + 1 < endofpath) {
+ if (xref > path) {
+ SendIOv(q, path - q);
+ SendIOv(s, xref - s);
+ SendIOv(VirtualPath, VirtualPathlen - 1);
+ SendIOv(r, p - r);
+ } else {
+ SendIOv(q, xref - q);
+ SendIOv(VirtualPath, VirtualPathlen - 1);
+ SendIOv(r, path - r);
+ SendIOv(s, p - s);
+ }
+ } else {
+ if (xref > path) {
+ SendIOv(q, path - q);
+ SendIOv(VirtualPath, VirtualPathlen);
+ SendIOv(path, xref - path);
+ SendIOv(VirtualPath, VirtualPathlen - 1);
+ SendIOv(r, p - r);
+ } else {
+ SendIOv(q, xref - q);
+ SendIOv(VirtualPath, VirtualPathlen - 1);
+ SendIOv(r, path - r);
+ SendIOv(VirtualPath, VirtualPathlen);
+ SendIOv(path, p - path);
+ }
+ }
+ } else
+ SendIOv(q, p - q);
+ ARTgetsize += p - q;
+ if (what == SThead) {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ } else if (memcmp((ARThandle->data + ARThandle->len - 5), "\r\n.\r\n", 5)) {
+ if (memcmp((ARThandle->data + ARThandle->len - 2), "\r\n", 2)) {
+ SendIOv("\r\n.\r\n", 5);
+ ARTgetsize += 5;
+ } else {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ }
+ }
+ PushIOv();
+
+ ARTget++;
+}
+
+/*
+** Return the header from the specified file, or NULL if not found.
+*/
+char *GetHeader(const char *header)
+{
+ const char *p, *q, *r, *s, *t;
+ char *w, prevchar;
+ /* Bogus value here to make sure that it isn't initialized to \n */
+ char lastchar = ' ';
+ const char *limit;
+ const char *cmplimit;
+ static char *retval = NULL;
+ static int retlen = 0;
+ int headerlen;
+ bool pathheader = false;
+ bool xrefheader = false;
+
+ limit = ARThandle->data + ARThandle->len;
+ cmplimit = ARThandle->data + ARThandle->len - strlen(header) - 1;
+ for (p = ARThandle->data; p < cmplimit; p++) {
+ if (*p == '\r')
+ continue;
+ if ((lastchar == '\n') && (*p == '\n')) {
+ return NULL;
+ }
+ if ((lastchar == '\n') || (p == ARThandle->data)) {
+ headerlen = strlen(header);
+ if (strncasecmp(p, header, headerlen) == 0 && p[headerlen] == ':') {
+ for (; (p < limit) && !isspace((int)*p) ; p++);
+ for (; (p < limit) && isspace((int)*p) ; p++);
+ for (q = p; q < limit; q++)
+ if ((*q == '\r') || (*q == '\n')) {
+ /* Check for continuation header lines */
+ t = q + 1;
+ if (t < limit) {
+ if ((*q == '\r' && *t == '\n')) {
+ t++;
+ if (t == limit)
+ break;
+ }
+ if ((*t == '\t' || *t == ' ')) {
+ for (; (t < limit) && isspace((int)*t) ; t++);
+ q = t;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ if (q == limit)
+ return NULL;
+ if (strncasecmp("Path", header, headerlen) == 0)
+ pathheader = true;
+ else if (strncasecmp("Xref", header, headerlen) == 0)
+ xrefheader = true;
+ if (retval == NULL) {
+ retlen = q - p + VirtualPathlen + 1;
+ retval = xmalloc(retlen);
+ } else {
+ if ((q - p + VirtualPathlen + 1) > retlen) {
+ retlen = q - p + VirtualPathlen + 1;
+ retval = xrealloc(retval, retlen);
+ }
+ }
+ if (pathheader && (VirtualPathlen > 0)) {
+ const char *endofpath;
+ const char *endofarticle;
+
+ endofarticle = ARThandle->data + ARThandle->len - 1;
+ endofpath = wire_endheader(p, endofarticle);
+ if (endofpath == NULL)
+ return NULL;
+ for (s = p, prevchar = '\0';
+ s + VirtualPathlen + 1 < endofpath;
+ prevchar = *s++) {
+ if ((prevchar != '\0' && prevchar != '!') ||
+ *s != *VirtualPath ||
+ strncmp(s, VirtualPath, VirtualPathlen - 1) != 0)
+ continue;
+ if (*(s + VirtualPathlen - 1) != '\0' &&
+ *(s + VirtualPathlen - 1) != '!')
+ continue;
+ break;
+ }
+ if (s + VirtualPathlen + 1 < endofpath) {
+ memcpy(retval, s, q - s);
+ *(retval + (int)(q - s)) = '\0';
+ } else {
+ memcpy(retval, VirtualPath, VirtualPathlen);
+ memcpy(retval + VirtualPathlen, p, q - p);
+ *(retval + (int)(q - p) + VirtualPathlen) = '\0';
+ }
+ } else if (xrefheader && (VirtualPathlen > 0)) {
+ if ((r = memchr(p, ' ', q - p)) == NULL)
+ return NULL;
+ for (; (r < q) && isspace((int)*r) ; r++);
+ if (r == q)
+ return NULL;
+ memcpy(retval, VirtualPath, VirtualPathlen - 1);
+ memcpy(retval + VirtualPathlen - 1, r - 1, q - r + 1);
+ *(retval + (int)(q - r) + VirtualPathlen) = '\0';
+ } else {
+ memcpy(retval, p, q - p);
+ *(retval + (int)(q - p)) = '\0';
+ }
+ for (w = retval; *w; w++)
+ if (*w == '\n' || *w == '\r')
+ *w = ' ';
+ return retval;
+ }
+ }
+ lastchar = *p;
+ }
+ return NULL;
+}
+
+/*
+** Fetch part or all of an article and send it to the client.
+*/
+void CMDfetch(int ac, char *av[])
+{
+ char buff[SMBUF];
+ SENDDATA *what;
+ bool ok;
+ ARTNUM art;
+ char *msgid;
+ ARTNUM tart;
+ bool final = false;
+
+ /* Find what to send; get permissions. */
+ ok = PERMcanread;
+ switch (*av[0]) {
+ default:
+ what = &SENDbody;
+ final = true;
+ break;
+ case 'a': case 'A':
+ what = &SENDarticle;
+ final = true;
+ break;
+ case 's': case 'S':
+ what = &SENDstat;
+ break;
+ case 'h': case 'H':
+ what = &SENDhead;
+ /* Poster might do a "head" command to verify the article. */
+ ok = PERMcanread || PERMcanpost;
+ break;
+ }
+
+ if (!ok) {
+ Reply("%s\r\n", NOACCESS);
+ return;
+ }
+
+ /* Requesting by Message-ID? */
+ if (ac == 2 && av[1][0] == '<') {
+ if (!ARTopenbyid(av[1], &art, final)) {
+ Reply("%d No such article\r\n", NNTP_DONTHAVEIT_VAL);
+ return;
+ }
+ if (!PERMartok()) {
+ ARTclose();
+ Reply("%s\r\n", NOACCESS);
+ return;
+ }
+ tart=art;
+ Reply("%d %lu %s %s\r\n", what->ReplyCode, (unsigned long) art,
+ av[1], what->Item);
+ if (what->Type != STstat) {
+ ARTsendmmap(what->Type);
+ }
+ ARTclose();
+ return;
+ }
+
+ /* Trying to read. */
+ if (GRPcount == 0) {
+ Reply("%s\r\n", ARTnotingroup);
+ return;
+ }
+
+ /* Default is to get current article, or specified article. */
+ if (ac == 1) {
+ if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
+ Reply("%s\r\n", ARTnocurrart);
+ return;
+ }
+ snprintf(buff, sizeof(buff), "%d", ARTnumber);
+ tart=ARTnumber;
+ }
+ else {
+ if (strspn(av[1], "0123456789") != strlen(av[1])) {
+ Reply("%s\r\n", ARTnoartingroup);
+ return;
+ }
+ strlcpy(buff, av[1], sizeof(buff));
+ tart=(ARTNUM)atol(buff);
+ }
+
+ /* Open the article and send the reply. */
+ if (!ARTopen(atol(buff))) {
+ Reply("%s\r\n", ARTnoartingroup);
+ return;
+ }
+ if (ac > 1)
+ ARTnumber = tart;
+ if ((msgid = GetHeader("Message-ID")) == NULL) {
+ Reply("%s\r\n", ARTnoartingroup);
+ return;
+ }
+ Reply("%d %s %.512s %s\r\n", what->ReplyCode, buff, msgid, what->Item);
+ if (what->Type != STstat)
+ ARTsendmmap(what->Type);
+ ARTclose();
+}
+
+
+/*
+** Go to the next or last (really previous) article in the group.
+*/
+void CMDnextlast(int ac UNUSED, char *av[])
+{
+ char *msgid;
+ int save, delta, errcode;
+ bool next;
+ const char *message;
+
+ if (!PERMcanread) {
+ Reply("%s\r\n", NOACCESS);
+ return;
+ }
+ if (GRPcount == 0) {
+ Reply("%s\r\n", ARTnotingroup);
+ return;
+ }
+ if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
+ Reply("%s\r\n", ARTnocurrart);
+ return;
+ }
+
+ next = (av[0][0] == 'n' || av[0][0] == 'N');
+ if (next) {
+ delta = 1;
+ errcode = NNTP_NONEXT_VAL;
+ message = "next";
+ }
+ else {
+ delta = -1;
+ errcode = NNTP_NOPREV_VAL;
+ message = "previous";
+ }
+
+ save = ARTnumber;
+ msgid = NULL;
+ do {
+ ARTnumber += delta;
+ if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
+ Reply("%d No %s to retrieve.\r\n", errcode, message);
+ ARTnumber = save;
+ return;
+ }
+ if (!ARTopen(ARTnumber))
+ continue;
+ msgid = GetHeader("Message-ID");
+ } while (msgid == NULL);
+
+ ARTclose();
+ Reply("%d %d %s Article retrieved; request text separately.\r\n",
+ NNTP_NOTHING_FOLLOWS_VAL, ARTnumber, msgid);
+}
+
+
+static bool CMDgetrange(int ac, char *av[], ARTRANGE *rp, bool *DidReply)
+{
+ char *p;
+
+ *DidReply = false;
+ if (GRPcount == 0) {
+ Reply("%s\r\n", ARTnotingroup);
+ *DidReply = true;
+ return false;
+ }
+
+ if (ac == 1) {
+ /* No argument, do only current article. */
+ if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
+ Reply("%s\r\n", ARTnocurrart);
+ *DidReply = true;
+ return false;
+ }
+ rp->High = rp->Low = ARTnumber;
+ return true;
+ }
+
+ /* Got just a single number? */
+ if ((p = strchr(av[1], '-')) == NULL) {
+ rp->Low = rp->High = atol(av[1]);
+ return true;
+ }
+
+ /* Parse range. */
+ *p++ = '\0';
+ rp->Low = atol(av[1]);
+ if (*p == '\0' || (rp->High = atol(p)) < rp->Low)
+ /* "XHDR 234-0 header" gives everything to the end. */
+ rp->High = ARThigh;
+ else if (rp->High > ARThigh)
+ rp->High = ARThigh;
+ if (rp->Low < ARTlow)
+ rp->Low = ARTlow;
+ p--;
+ *p = '-';
+
+ return true;
+}
+
+
+/*
+** Apply virtual hosting to an Xref field.
+*/
+static char *
+vhost_xref(char *p)
+{
+ char *space;
+ size_t offset;
+ char *field = NULL;
+
+ space = strchr(p, ' ');
+ if (space == NULL) {
+ warn("malformed Xref `%s'", field);
+ goto fail;
+ }
+ offset = space + 1 - p;
+ space = strchr(p + offset, ' ');
+ if (space == NULL) {
+ warn("malformed Xref `%s'", field);
+ goto fail;
+ }
+ field = concat(PERMaccessconf->domain, space, NULL);
+ fail:
+ free(p);
+ return field;
+}
+
+/*
+** XOVER another extension. Dump parts of the overview database.
+*/
+void CMDxover(int ac, char *av[])
+{
+ bool DidReply;
+ ARTRANGE range;
+ struct timeval stv, etv;
+ ARTNUM artnum;
+ void *handle;
+ char *data, *r;
+ const char *p, *q;
+ int len, useIOb = 0;
+ TOKEN token;
+ struct cvector *vector = NULL;
+
+ if (!PERMcanread) {
+ Printf("%s\r\n", NOACCESS);
+ return;
+ }
+
+ /* Trying to read. */
+ if (GRPcount == 0) {
+ Reply("%s\r\n", ARTnotingroup);
+ return;
+ }
+
+ /* Parse range. */
+ if (!CMDgetrange(ac, av, &range, &DidReply)) {
+ if (!DidReply) {
+ Reply("%d data follows\r\n", NNTP_OVERVIEW_FOLLOWS_VAL);
+ Printf(".\r\n");
+ return;
+ }
+ }
+
+ OVERcount++;
+ gettimeofday(&stv, NULL);
+ if ((handle = (void *)OVopensearch(GRPcur, range.Low, range.High)) == NULL) {
+ if (av[1] != NULL)
+ Reply("%d %s fields follow\r\n.\r\n", NNTP_OVERVIEW_FOLLOWS_VAL, av[1]);
+ else
+ Reply("%d %d fields follow\r\n.\r\n", NNTP_OVERVIEW_FOLLOWS_VAL, ARTnumber);
+ return;
+ }
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&etv, NULL);
+ OVERtime+=(etv.tv_sec - stv.tv_sec) * 1000;
+ OVERtime+=(etv.tv_usec - stv.tv_usec) / 1000;
+ }
+
+ if (av[1] != NULL)
+ Reply("%d %s fields follow\r\n", NNTP_OVERVIEW_FOLLOWS_VAL, av[1]);
+ else
+ Reply("%d %d fields follow\r\n", NNTP_OVERVIEW_FOLLOWS_VAL, ARTnumber);
+ fflush(stdout);
+ if (PERMaccessconf->nnrpdoverstats)
+ gettimeofday(&stv, NULL);
+
+ /* If OVSTATICSEARCH is true, then the data returned by OVsearch is only
+ valid until the next call to OVsearch. In this case, we must use
+ SendIOb because it copies the data. */
+ OVctl(OVSTATICSEARCH, &useIOb);
+
+ while (OVsearch(handle, &artnum, &data, &len, &token, NULL)) {
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&etv, NULL);
+ OVERtime+=(etv.tv_sec - stv.tv_sec) * 1000;
+ OVERtime+=(etv.tv_usec - stv.tv_usec) / 1000;
+ }
+ if (len == 0 || (PERMaccessconf->nnrpdcheckart && !ARTinstorebytoken(token))) {
+ if (PERMaccessconf->nnrpdoverstats) {
+ OVERmiss++;
+ gettimeofday(&stv, NULL);
+ }
+ continue;
+ }
+ if (PERMaccessconf->nnrpdoverstats) {
+ OVERhit++;
+ OVERsize += len;
+ }
+ vector = overview_split(data, len, NULL, vector);
+ r = overview_getheader(vector, OVERVIEW_MESSAGE_ID, OVextra);
+ cache_add(HashMessageID(r), token);
+ free(r);
+ if (VirtualPathlen > 0 && overhdr_xref != -1) {
+ if ((overhdr_xref + 1) >= vector->count)
+ continue;
+ p = vector->strings[overhdr_xref] + sizeof("Xref: ") - 1;
+ while ((p < data + len) && *p == ' ')
+ ++p;
+ q = memchr(p, ' ', data + len - p);
+ if (q == NULL)
+ continue;
+ if(useIOb) {
+ SendIOb(data, p - data);
+ SendIOb(VirtualPath, VirtualPathlen - 1);
+ SendIOb(q, len - (q - data));
+ } else {
+ SendIOv(data, p - data);
+ SendIOv(VirtualPath, VirtualPathlen - 1);
+ SendIOv(q, len - (q - data));
+ }
+ } else {
+ if(useIOb)
+ SendIOb(data, len);
+ else
+ SendIOv(data, len);
+ }
+ if (PERMaccessconf->nnrpdoverstats)
+ gettimeofday(&stv, NULL);
+ }
+
+ if (vector)
+ cvector_free(vector);
+
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&etv, NULL);
+ OVERtime+=(etv.tv_sec - stv.tv_sec) * 1000;
+ OVERtime+=(etv.tv_usec - stv.tv_usec) / 1000;
+ }
+ if(useIOb) {
+ SendIOb(".\r\n", 3);
+ PushIOb();
+ } else {
+ SendIOv(".\r\n", 3);
+ PushIOv();
+ }
+ if (PERMaccessconf->nnrpdoverstats)
+ gettimeofday(&stv, NULL);
+ OVclosesearch(handle);
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&etv, NULL);
+ OVERtime+=(etv.tv_sec - stv.tv_sec) * 1000;
+ OVERtime+=(etv.tv_usec - stv.tv_usec) / 1000;
+ }
+
+}
+
+/*
+** XHDR and XPAT extensions. Note that HDR as specified in the new NNTP
+** draft works differently than XHDR has historically, so don't just use this
+** function to implement it without reviewing the differences.
+*/
+/* ARGSUSED */
+void CMDpat(int ac, char *av[])
+{
+ char *p;
+ int i;
+ ARTRANGE range;
+ bool IsLines;
+ bool DidReply;
+ char *header;
+ char *pattern;
+ char *text;
+ int Overview;
+ ARTNUM artnum;
+ char buff[SPOOLNAMEBUFF];
+ void *handle;
+ char *data;
+ int len;
+ TOKEN token;
+ struct cvector *vector = NULL;
+
+ if (!PERMcanread) {
+ Printf("%s\r\n", NOACCESS);
+ return;
+ }
+
+ header = av[1];
+ IsLines = (strcasecmp(header, "lines") == 0);
+
+ if (ac > 3) /* XPAT */
+ pattern = Glom(&av[3]);
+ else
+ pattern = NULL;
+
+ do {
+ /* Message-ID specified? */
+ if (ac > 2 && av[2][0] == '<') {
+ p = av[2];
+ if (!ARTopenbyid(p, &artnum, false)) {
+ Printf("%d No such article.\r\n", NNTP_DONTHAVEIT_VAL);
+ break;
+ }
+ Printf("%d %s matches follow (ID)\r\n", NNTP_HEAD_FOLLOWS_VAL,
+ header);
+ if ((text = GetHeader(header)) != NULL
+ && (!pattern || uwildmat_simple(text, pattern)))
+ Printf("%s %s\r\n", p, text);
+
+ ARTclose();
+ Printf(".\r\n");
+ break;
+ }
+
+ if (GRPcount == 0) {
+ Reply("%s\r\n", ARTnotingroup);
+ break;
+ }
+
+ /* Range specified. */
+ if (!CMDgetrange(ac - 1, av + 1, &range, &DidReply)) {
+ if (!DidReply) {
+ Reply("%d %s no matches follow (range)\r\n",
+ NNTP_HEAD_FOLLOWS_VAL, header ? header : "\"\"");
+ Printf(".\r\n");
+ break;
+ }
+ }
+
+ /* In overview? */
+ Overview = overview_index(header, OVextra);
+
+ /* Not in overview, we have to fish headers out from the articles */
+ if (Overview < 0 ) {
+ Reply("%d %s matches follow (art)\r\n", NNTP_HEAD_FOLLOWS_VAL,
+ header);
+ for (i = range.Low; i <= range.High && range.High > 0; i++) {
+ if (!ARTopen(i))
+ continue;
+ p = GetHeader(header);
+ if (p && (!pattern || uwildmat_simple(p, pattern))) {
+ snprintf(buff, sizeof(buff), "%u ", i);
+ SendIOb(buff, strlen(buff));
+ SendIOb(p, strlen(p));
+ SendIOb("\r\n", 2);
+ ARTclose();
+ }
+ }
+ SendIOb(".\r\n", 3);
+ PushIOb();
+ break;
+ }
+
+ /* Okay then, we can grab values from overview. */
+ handle = (void *)OVopensearch(GRPcur, range.Low, range.High);
+ if (handle == NULL) {
+ Reply("%d %s no matches follow (NOV)\r\n.\r\n",
+ NNTP_HEAD_FOLLOWS_VAL, header);
+ break;
+ }
+
+ Printf("%d %s matches follow (NOV)\r\n", NNTP_HEAD_FOLLOWS_VAL,
+ header);
+ while (OVsearch(handle, &artnum, &data, &len, &token, NULL)) {
+ if (len == 0 || (PERMaccessconf->nnrpdcheckart
+ && !ARTinstorebytoken(token)))
+ continue;
+ vector = overview_split(data, len, NULL, vector);
+ p = overview_getheader(vector, Overview, OVextra);
+ if (p != NULL) {
+ if (PERMaccessconf->virtualhost &&
+ Overview == overhdr_xref) {
+ p = vhost_xref(p);
+ if (p == NULL)
+ continue;
+ }
+ if (!pattern || uwildmat_simple(p, pattern)) {
+ snprintf(buff, sizeof(buff), "%lu ", artnum);
+ SendIOb(buff, strlen(buff));
+ SendIOb(p, strlen(p));
+ SendIOb("\r\n", 2);
+ }
+ free(p);
+ }
+ }
+ SendIOb(".\r\n", 3);
+ PushIOb();
+ OVclosesearch(handle);
+ } while (0);
+
+ if (vector)
+ cvector_free(vector);
+
+ if (pattern)
+ free(pattern);
+}
--- /dev/null
+/* $Id: article.c 7538 2006-08-26 05:44:06Z eagle $
+**
+** Article-related routines.
+*/
+
+#include "config.h"
+#include "clibrary.h"
+#include <assert.h>
+#if HAVE_LIMITS_H
+# include <limits.h>
+#endif
+#include <sys/uio.h>
+
+#include "inn/innconf.h"
+#include "inn/messages.h"
+#include "inn/wire.h"
+#include "nnrpd.h"
+#include "ov.h"
+#include "tls.h"
+#include "cache.h"
+
+#ifdef HAVE_SSL
+extern SSL *tls_conn;
+#endif
+
+/*
+** Data structures for use in ARTICLE/HEAD/BODY/STAT common code.
+*/
+typedef enum _SENDTYPE {
+ STarticle,
+ SThead,
+ STbody,
+ STstat
+} SENDTYPE;
+
+typedef struct _SENDDATA {
+ SENDTYPE Type;
+ int ReplyCode;
+ const char *Item;
+} SENDDATA;
+
+static char ARTnotingroup[] = NNTP_NOTINGROUP;
+static char ARTnoartingroup[] = NNTP_NOARTINGRP;
+static char ARTnocurrart[] = NNTP_NOCURRART;
+static ARTHANDLE *ARThandle = NULL;
+static SENDDATA SENDbody = {
+ STbody, NNTP_BODY_FOLLOWS_VAL, "body"
+};
+static SENDDATA SENDarticle = {
+ STarticle, NNTP_ARTICLE_FOLLOWS_VAL, "article"
+};
+static SENDDATA SENDstat = {
+ STstat, NNTP_NOTHING_FOLLOWS_VAL, "status"
+};
+static SENDDATA SENDhead = {
+ SThead, NNTP_HEAD_FOLLOWS_VAL, "head"
+};
+
+
+static struct iovec iov[IOV_MAX > 1024 ? 1024 : IOV_MAX];
+static int queued_iov = 0;
+
+static void PushIOvHelper(struct iovec* vec, int* countp) {
+ int result;
+ TMRstart(TMR_NNTPWRITE);
+#ifdef HAVE_SSL
+ if (tls_conn) {
+Again:
+ result = SSL_writev(tls_conn, vec, *countp);
+ switch (SSL_get_error(tls_conn, result)) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_SYSCALL:
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ goto Again;
+ break;
+ case SSL_ERROR_SSL:
+ SSL_shutdown(tls_conn);
+ tls_conn = NULL;
+ errno = ECONNRESET;
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ break;
+ }
+ } else {
+ result = xwritev(STDOUT_FILENO, vec, *countp);
+ }
+#else
+ result = xwritev(STDOUT_FILENO, vec, *countp);
+#endif
+ TMRstop(TMR_NNTPWRITE);
+ if (result == -1) {
+ /* we can't recover, since we can't resynchronise with our
+ * peer */
+ ExitWithStats(1, true);
+ }
+ *countp = 0;
+}
+
+static void
+PushIOvRateLimited(void) {
+ double start, end, elapsed, target;
+ struct iovec newiov[IOV_MAX > 1024 ? 1024 : IOV_MAX];
+ int newiov_len;
+ int sentiov;
+ int i;
+ int bytesfound;
+ int chunkbittenoff;
+ struct timeval waittime;
+
+ while (queued_iov) {
+ bytesfound = newiov_len = 0;
+ sentiov = 0;
+ for (i = 0; (i < queued_iov) && (bytesfound < MaxBytesPerSecond); i++) {
+ if ((signed)iov[i].iov_len + bytesfound > MaxBytesPerSecond) {
+ chunkbittenoff = MaxBytesPerSecond - bytesfound;
+ newiov[newiov_len].iov_base = iov[i].iov_base;
+ newiov[newiov_len++].iov_len = chunkbittenoff;
+ iov[i].iov_base = (char *)iov[i].iov_base + chunkbittenoff;
+ iov[i].iov_len -= chunkbittenoff;
+ bytesfound += chunkbittenoff;
+ } else {
+ newiov[newiov_len++] = iov[i];
+ sentiov++;
+ bytesfound += iov[i].iov_len;
+ }
+ }
+ assert(sentiov <= queued_iov);
+ start = TMRnow_double();
+ PushIOvHelper(newiov, &newiov_len);
+ end = TMRnow_double();
+ target = (double) bytesfound / MaxBytesPerSecond;
+ elapsed = end - start;
+ if (elapsed < 1 && elapsed < target) {
+ waittime.tv_sec = 0;
+ waittime.tv_usec = (target - elapsed) * 1e6;
+ start = TMRnow_double();
+ if (select(0, NULL, NULL, NULL, &waittime) != 0)
+ syswarn("%s: select in PushIOvRateLimit failed", ClientHost);
+ end = TMRnow_double();
+ IDLEtime += end - start;
+ }
+ memmove(iov, &iov[sentiov], (queued_iov - sentiov) * sizeof(struct iovec));
+ queued_iov -= sentiov;
+ }
+}
+
+static void
+PushIOv(void) {
+ TMRstart(TMR_NNTPWRITE);
+ fflush(stdout);
+ TMRstop(TMR_NNTPWRITE);
+ if (MaxBytesPerSecond != 0)
+ PushIOvRateLimited();
+ else
+ PushIOvHelper(iov, &queued_iov);
+}
+
+static void
+SendIOv(const char *p, int len) {
+ char *q;
+
+ if (queued_iov) {
+ q = (char *)iov[queued_iov - 1].iov_base + iov[queued_iov - 1].iov_len;
+ if (p == q) {
+ iov[queued_iov - 1].iov_len += len;
+ return;
+ }
+ }
+ iov[queued_iov].iov_base = (char*)p;
+ iov[queued_iov++].iov_len = len;
+ if (queued_iov == IOV_MAX)
+ PushIOv();
+}
+
+static char *_IO_buffer_ = NULL;
+static int highwater = 0;
+
+static void
+PushIOb(void) {
+ TMRstart(TMR_NNTPWRITE);
+ fflush(stdout);
+#ifdef HAVE_SSL
+ if (tls_conn) {
+ int r;
+Again:
+ r = SSL_write(tls_conn, _IO_buffer_, highwater);
+ switch (SSL_get_error(tls_conn, r)) {
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_SYSCALL:
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ goto Again;
+ break;
+ case SSL_ERROR_SSL:
+ SSL_shutdown(tls_conn);
+ tls_conn = NULL;
+ errno = ECONNRESET;
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ break;
+ }
+ if (r != highwater) {
+ TMRstop(TMR_NNTPWRITE);
+ highwater = 0;
+ return;
+ }
+ } else {
+ if (xwrite(STDOUT_FILENO, _IO_buffer_, highwater) != highwater) {
+ TMRstop(TMR_NNTPWRITE);
+ highwater = 0;
+ return;
+ }
+ }
+#else
+ if (xwrite(STDOUT_FILENO, _IO_buffer_, highwater) != highwater) {
+ TMRstop(TMR_NNTPWRITE);
+ highwater = 0;
+ return;
+ }
+#endif
+ TMRstop(TMR_NNTPWRITE);
+ highwater = 0;
+}
+
+static void
+SendIOb(const char *p, int len) {
+ int tocopy;
+
+ if (_IO_buffer_ == NULL)
+ _IO_buffer_ = xmalloc(BIG_BUFFER);
+
+ while (len > 0) {
+ tocopy = (len > (BIG_BUFFER - highwater)) ? (BIG_BUFFER - highwater) : len;
+ memcpy(&_IO_buffer_[highwater], p, tocopy);
+ p += tocopy;
+ highwater += tocopy;
+ len -= tocopy;
+ if (highwater == BIG_BUFFER)
+ PushIOb();
+ }
+}
+
+
+/*
+** If we have an article open, close it.
+*/
+void ARTclose(void)
+{
+ if (ARThandle) {
+ SMfreearticle(ARThandle);
+ ARThandle = NULL;
+ }
+}
+
+bool ARTinstorebytoken(TOKEN token)
+{
+ ARTHANDLE *art;
+ struct timeval stv, etv;
+
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&stv, NULL);
+ }
+ art = SMretrieve(token, RETR_STAT); /* XXX This isn't really overstats, is it? */
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&etv, NULL);
+ OVERartcheck+=(etv.tv_sec - stv.tv_sec) * 1000;
+ OVERartcheck+=(etv.tv_usec - stv.tv_usec) / 1000;
+ }
+ if (art) {
+ SMfreearticle(art);
+ return true;
+ }
+ return false;
+}
+
+/*
+** If the article name is valid, open it and stuff in the ID.
+*/
+static bool ARTopen(ARTNUM artnum)
+{
+ static ARTNUM save_artnum;
+ TOKEN token;
+
+ /* Re-use article if it's the same one. */
+ if (save_artnum == artnum) {
+ if (ARThandle)
+ return true;
+ }
+ ARTclose();
+
+ if (!OVgetartinfo(GRPcur, artnum, &token))
+ return false;
+
+ TMRstart(TMR_READART);
+ ARThandle = SMretrieve(token, RETR_ALL);
+ TMRstop(TMR_READART);
+ if (ARThandle == NULL) {
+ return false;
+ }
+
+ save_artnum = artnum;
+ return true;
+}
+
+
+/*
+** Open the article for a given Message-ID.
+*/
+static bool
+ARTopenbyid(char *msg_id, ARTNUM *ap, bool final)
+{
+ TOKEN token;
+
+ *ap = 0;
+ token = cache_get(HashMessageID(msg_id), final);
+ if (token.type == TOKEN_EMPTY) {
+ if (History == NULL) {
+ time_t statinterval;
+
+ /* Do lazy opens of the history file - lots of clients
+ * will never ask for anything by message id, so put off
+ * doing the work until we have to */
+ History = HISopen(HISTORY, innconf->hismethod, HIS_RDONLY);
+ if (!History) {
+ syslog(L_NOTICE, "cant initialize history");
+ Reply("%d NNTP server unavailable. Try later.\r\n",
+ NNTP_TEMPERR_VAL);
+ ExitWithStats(1, true);
+ }
+ statinterval = 30;
+ HISctl(History, HISCTLS_STATINTERVAL, &statinterval);
+ }
+ if (!HISlookup(History, msg_id, NULL, NULL, NULL, &token))
+ return false;
+ }
+ if (token.type == TOKEN_EMPTY)
+ return false;
+ TMRstart(TMR_READART);
+ ARThandle = SMretrieve(token, RETR_ALL);
+ TMRstop(TMR_READART);
+ if (ARThandle == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+/*
+** Send a (part of) a file to stdout, doing newline and dot conversion.
+*/
+static void ARTsendmmap(SENDTYPE what)
+{
+ const char *p, *q, *r;
+ const char *s, *path, *xref, *endofpath;
+ long bytecount;
+ char lastchar;
+
+ ARTcount++;
+ GRParticles++;
+ bytecount = 0;
+ lastchar = -1;
+
+ /* Get the headers and detect if wire format. */
+ if (what == STarticle) {
+ q = ARThandle->data;
+ p = ARThandle->data + ARThandle->len;
+ } else {
+ for (q = p = ARThandle->data; p < (ARThandle->data + ARThandle->len); p++) {
+ if (*p == '\r')
+ continue;
+ if (*p == '\n') {
+ if (lastchar == '\n') {
+ if (what == SThead) {
+ if (*(p-1) == '\r')
+ p--;
+ break;
+ } else {
+ q = p + 1;
+ p = ARThandle->data + ARThandle->len;
+ break;
+ }
+ }
+ }
+ lastchar = *p;
+ }
+ }
+
+ /* q points to the start of the article buffer, p to the end of it */
+ if (VirtualPathlen > 0 && (what != STbody)) {
+ path = wire_findheader(ARThandle->data, ARThandle->len, "Path");
+ if (path == NULL) {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ PushIOv();
+ ARTget++;
+ return;
+ } else {
+ xref = wire_findheader(ARThandle->data, ARThandle->len, "Xref");
+ if (xref == NULL) {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ PushIOv();
+ ARTget++;
+ return;
+ }
+ }
+ endofpath = wire_endheader(path, ARThandle->data + ARThandle->len - 1);
+ if (endofpath == NULL) {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ PushIOv();
+ ARTget++;
+ return;
+ }
+ if ((r = memchr(xref, ' ', p - xref)) == NULL || r == p) {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ PushIOv();
+ ARTget++;
+ return;
+ }
+ /* r points to the first space in the Xref header */
+ for (s = path, lastchar = '\0';
+ s + VirtualPathlen + 1 < endofpath;
+ lastchar = *s++) {
+ if ((lastchar != '\0' && lastchar != '!') || *s != *VirtualPath ||
+ strncmp(s, VirtualPath, VirtualPathlen - 1) != 0)
+ continue;
+ if (*(s + VirtualPathlen - 1) != '\0' &&
+ *(s + VirtualPathlen - 1) != '!')
+ continue;
+ break;
+ }
+ if (s + VirtualPathlen + 1 < endofpath) {
+ if (xref > path) {
+ SendIOv(q, path - q);
+ SendIOv(s, xref - s);
+ SendIOv(VirtualPath, VirtualPathlen - 1);
+ SendIOv(r, p - r);
+ } else {
+ SendIOv(q, xref - q);
+ SendIOv(VirtualPath, VirtualPathlen - 1);
+ SendIOv(r, path - r);
+ SendIOv(s, p - s);
+ }
+ } else {
+ if (xref > path) {
+ SendIOv(q, path - q);
+ SendIOv(VirtualPath, VirtualPathlen);
+ SendIOv(path, xref - path);
+ SendIOv(VirtualPath, VirtualPathlen - 1);
+ SendIOv(r, p - r);
+ } else {
+ SendIOv(q, xref - q);
+ SendIOv(VirtualPath, VirtualPathlen - 1);
+ SendIOv(r, path - r);
+ SendIOv(VirtualPath, VirtualPathlen);
+ SendIOv(path, p - path);
+ }
+ }
+ } else
+ SendIOv(q, p - q);
+ ARTgetsize += p - q;
+ if (what == SThead) {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ } else if (memcmp((ARThandle->data + ARThandle->len - 5), "\r\n.\r\n", 5)) {
+ if (memcmp((ARThandle->data + ARThandle->len - 2), "\r\n", 2)) {
+ SendIOv("\r\n.\r\n", 5);
+ ARTgetsize += 5;
+ } else {
+ SendIOv(".\r\n", 3);
+ ARTgetsize += 3;
+ }
+ }
+ PushIOv();
+
+ ARTget++;
+}
+
+/*
+** Return the header from the specified file, or NULL if not found.
+*/
+char *GetHeader(const char *header)
+{
+ const char *p, *q, *r, *s, *t;
+ char *w, prevchar;
+ /* Bogus value here to make sure that it isn't initialized to \n */
+ char lastchar = ' ';
+ const char *limit;
+ const char *cmplimit;
+ static char *retval = NULL;
+ static int retlen = 0;
+ int headerlen;
+ bool pathheader = false;
+ bool xrefheader = false;
+
+ limit = ARThandle->data + ARThandle->len;
+ cmplimit = ARThandle->data + ARThandle->len - strlen(header) - 1;
+ for (p = ARThandle->data; p < cmplimit; p++) {
+ if (*p == '\r')
+ continue;
+ if ((lastchar == '\n') && (*p == '\n')) {
+ return NULL;
+ }
+ if ((lastchar == '\n') || (p == ARThandle->data)) {
+ headerlen = strlen(header);
+ if (strncasecmp(p, header, headerlen) == 0 && p[headerlen] == ':') {
+ for (; (p < limit) && !isspace((int)*p) ; p++);
+ for (; (p < limit) && isspace((int)*p) ; p++);
+ for (q = p; q < limit; q++)
+ if ((*q == '\r') || (*q == '\n')) {
+ /* Check for continuation header lines */
+ t = q + 1;
+ if (t < limit) {
+ if ((*q == '\r' && *t == '\n')) {
+ t++;
+ if (t == limit)
+ break;
+ }
+ if ((*t == '\t' || *t == ' ')) {
+ for (; (t < limit) && isspace((int)*t) ; t++);
+ q = t;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ if (q == limit)
+ return NULL;
+ if (strncasecmp("Path", header, headerlen) == 0)
+ pathheader = true;
+ else if (strncasecmp("Xref", header, headerlen) == 0)
+ xrefheader = true;
+ if (retval == NULL) {
+ retlen = q - p + VirtualPathlen + 1;
+ retval = xmalloc(retlen);
+ } else {
+ if ((q - p + VirtualPathlen + 1) > retlen) {
+ retlen = q - p + VirtualPathlen + 1;
+ retval = xrealloc(retval, retlen);
+ }
+ }
+ if (pathheader && (VirtualPathlen > 0)) {
+ const char *endofpath;
+ const char *endofarticle;
+
+ endofarticle = ARThandle->data + ARThandle->len - 1;
+ endofpath = wire_endheader(p, endofarticle);
+ if (endofpath == NULL)
+ return NULL;
+ for (s = p, prevchar = '\0';
+ s + VirtualPathlen + 1 < endofpath;
+ prevchar = *s++) {
+ if ((prevchar != '\0' && prevchar != '!') ||
+ *s != *VirtualPath ||
+ strncmp(s, VirtualPath, VirtualPathlen - 1) != 0)
+ continue;
+ if (*(s + VirtualPathlen - 1) != '\0' &&
+ *(s + VirtualPathlen - 1) != '!')
+ continue;
+ break;
+ }
+ if (s + VirtualPathlen + 1 < endofpath) {
+ memcpy(retval, s, q - s);
+ *(retval + (int)(q - s)) = '\0';
+ } else {
+ memcpy(retval, VirtualPath, VirtualPathlen);
+ memcpy(retval + VirtualPathlen, p, q - p);
+ *(retval + (int)(q - p) + VirtualPathlen) = '\0';
+ }
+ } else if (xrefheader && (VirtualPathlen > 0)) {
+ if ((r = memchr(p, ' ', q - p)) == NULL)
+ return NULL;
+ for (; (r < q) && isspace((int)*r) ; r++);
+ if (r == q)
+ return NULL;
+ memcpy(retval, VirtualPath, VirtualPathlen - 1);
+ memcpy(retval + VirtualPathlen - 1, r - 1, q - r + 1);
+ *(retval + (int)(q - r) + VirtualPathlen) = '\0';
+ } else {
+ memcpy(retval, p, q - p);
+ *(retval + (int)(q - p)) = '\0';
+ }
+ for (w = retval; *w; w++)
+ if (*w == '\n' || *w == '\r')
+ *w = ' ';
+ return retval;
+ }
+ }
+ lastchar = *p;
+ }
+ return NULL;
+}
+
+/*
+** Fetch part or all of an article and send it to the client.
+*/
+void CMDfetch(int ac, char *av[])
+{
+ char buff[SMBUF];
+ SENDDATA *what;
+ bool ok;
+ ARTNUM art;
+ char *msgid;
+ ARTNUM tart;
+ bool final = false;
+
+ /* Find what to send; get permissions. */
+ ok = PERMcanread;
+ switch (*av[0]) {
+ default:
+ what = &SENDbody;
+ final = true;
+ break;
+ case 'a': case 'A':
+ what = &SENDarticle;
+ final = true;
+ break;
+ case 's': case 'S':
+ what = &SENDstat;
+ break;
+ case 'h': case 'H':
+ what = &SENDhead;
+ /* Poster might do a "head" command to verify the article. */
+ ok = PERMcanread || PERMcanpost;
+ break;
+ }
+
+ if (!ok) {
+ Reply("%s\r\n", NOACCESS);
+ return;
+ }
+
+ /* Requesting by Message-ID? */
+ if (ac == 2 && av[1][0] == '<') {
+ if (!ARTopenbyid(av[1], &art, final)) {
+ Reply("%d No such article\r\n", NNTP_DONTHAVEIT_VAL);
+ return;
+ }
+ if (!PERMartok()) {
+ ARTclose();
+ Reply("%s\r\n", NOACCESS);
+ return;
+ }
+ tart=art;
+ Reply("%d %lu %s %s\r\n", what->ReplyCode, (unsigned long) art,
+ av[1], what->Item);
+ if (what->Type != STstat) {
+ ARTsendmmap(what->Type);
+ }
+ ARTclose();
+ return;
+ }
+
+ /* Trying to read. */
+ if (GRPcount == 0) {
+ Reply("%s\r\n", ARTnotingroup);
+ return;
+ }
+
+ /* Default is to get current article, or specified article. */
+ if (ac == 1) {
+ if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
+ Reply("%s\r\n", ARTnocurrart);
+ return;
+ }
+ snprintf(buff, sizeof(buff), "%d", ARTnumber);
+ tart=ARTnumber;
+ }
+ else {
+ if (strspn(av[1], "0123456789") != strlen(av[1])) {
+ Reply("%s\r\n", ARTnoartingroup);
+ return;
+ }
+ strlcpy(buff, av[1], sizeof(buff));
+ tart=(ARTNUM)atol(buff);
+ }
+
+ /* Open the article and send the reply. */
+ if (!ARTopen(atol(buff))) {
+ Reply("%s\r\n", ARTnoartingroup);
+ return;
+ }
+ if (ac > 1)
+ ARTnumber = tart;
+ if ((msgid = GetHeader("Message-ID")) == NULL) {
+ ARTclose();
+ Reply("%s\r\n", ARTnoartingroup);
+ return;
+ }
+ Reply("%d %s %.512s %s\r\n", what->ReplyCode, buff, msgid, what->Item);
+ if (what->Type != STstat)
+ ARTsendmmap(what->Type);
+ ARTclose();
+}
+
+
+/*
+** Go to the next or last (really previous) article in the group.
+*/
+void CMDnextlast(int ac UNUSED, char *av[])
+{
+ char *msgid;
+ int save, delta, errcode;
+ bool next;
+ const char *message;
+
+ if (!PERMcanread) {
+ Reply("%s\r\n", NOACCESS);
+ return;
+ }
+ if (GRPcount == 0) {
+ Reply("%s\r\n", ARTnotingroup);
+ return;
+ }
+ if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
+ Reply("%s\r\n", ARTnocurrart);
+ return;
+ }
+
+ next = (av[0][0] == 'n' || av[0][0] == 'N');
+ if (next) {
+ delta = 1;
+ errcode = NNTP_NONEXT_VAL;
+ message = "next";
+ }
+ else {
+ delta = -1;
+ errcode = NNTP_NOPREV_VAL;
+ message = "previous";
+ }
+
+ save = ARTnumber;
+ msgid = NULL;
+ do {
+ ARTnumber += delta;
+ if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
+ Reply("%d No %s to retrieve.\r\n", errcode, message);
+ ARTnumber = save;
+ return;
+ }
+ if (!ARTopen(ARTnumber))
+ continue;
+ msgid = GetHeader("Message-ID");
+ ARTclose();
+ } while (msgid == NULL);
+
+ Reply("%d %d %s Article retrieved; request text separately.\r\n",
+ NNTP_NOTHING_FOLLOWS_VAL, ARTnumber, msgid);
+}
+
+
+static bool CMDgetrange(int ac, char *av[], ARTRANGE *rp, bool *DidReply)
+{
+ char *p;
+
+ *DidReply = false;
+ if (GRPcount == 0) {
+ Reply("%s\r\n", ARTnotingroup);
+ *DidReply = true;
+ return false;
+ }
+
+ if (ac == 1) {
+ /* No argument, do only current article. */
+ if (ARTnumber < ARTlow || ARTnumber > ARThigh) {
+ Reply("%s\r\n", ARTnocurrart);
+ *DidReply = true;
+ return false;
+ }
+ rp->High = rp->Low = ARTnumber;
+ return true;
+ }
+
+ /* Got just a single number? */
+ if ((p = strchr(av[1], '-')) == NULL) {
+ rp->Low = rp->High = atol(av[1]);
+ return true;
+ }
+
+ /* Parse range. */
+ *p++ = '\0';
+ rp->Low = atol(av[1]);
+ if (*p == '\0' || (rp->High = atol(p)) < rp->Low)
+ /* "XHDR 234-0 header" gives everything to the end. */
+ rp->High = ARThigh;
+ else if (rp->High > ARThigh)
+ rp->High = ARThigh;
+ if (rp->Low < ARTlow)
+ rp->Low = ARTlow;
+ p--;
+ *p = '-';
+
+ return true;
+}
+
+
+/*
+** Apply virtual hosting to an Xref field.
+*/
+static char *
+vhost_xref(char *p)
+{
+ char *space;
+ size_t offset;
+ char *field = NULL;
+
+ space = strchr(p, ' ');
+ if (space == NULL) {
+ warn("malformed Xref `%s'", field);
+ goto fail;
+ }
+ offset = space + 1 - p;
+ space = strchr(p + offset, ' ');
+ if (space == NULL) {
+ warn("malformed Xref `%s'", field);
+ goto fail;
+ }
+ field = concat(PERMaccessconf->domain, space, NULL);
+ fail:
+ free(p);
+ return field;
+}
+
+/*
+** XOVER another extension. Dump parts of the overview database.
+*/
+void CMDxover(int ac, char *av[])
+{
+ bool DidReply;
+ ARTRANGE range;
+ struct timeval stv, etv;
+ ARTNUM artnum;
+ void *handle;
+ char *data, *r;
+ const char *p, *q;
+ int len, useIOb = 0;
+ TOKEN token;
+ struct cvector *vector = NULL;
+
+ if (!PERMcanread) {
+ Printf("%s\r\n", NOACCESS);
+ return;
+ }
+
+ /* Trying to read. */
+ if (GRPcount == 0) {
+ Reply("%s\r\n", ARTnotingroup);
+ return;
+ }
+
+ /* Parse range. */
+ if (!CMDgetrange(ac, av, &range, &DidReply)) {
+ if (!DidReply) {
+ Reply("%d data follows\r\n", NNTP_OVERVIEW_FOLLOWS_VAL);
+ Printf(".\r\n");
+ return;
+ }
+ }
+
+ OVERcount++;
+ gettimeofday(&stv, NULL);
+ if ((handle = (void *)OVopensearch(GRPcur, range.Low, range.High)) == NULL) {
+ if (av[1] != NULL)
+ Reply("%d %s fields follow\r\n.\r\n", NNTP_OVERVIEW_FOLLOWS_VAL, av[1]);
+ else
+ Reply("%d %d fields follow\r\n.\r\n", NNTP_OVERVIEW_FOLLOWS_VAL, ARTnumber);
+ return;
+ }
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&etv, NULL);
+ OVERtime+=(etv.tv_sec - stv.tv_sec) * 1000;
+ OVERtime+=(etv.tv_usec - stv.tv_usec) / 1000;
+ }
+
+ if (av[1] != NULL)
+ Reply("%d %s fields follow\r\n", NNTP_OVERVIEW_FOLLOWS_VAL, av[1]);
+ else
+ Reply("%d %d fields follow\r\n", NNTP_OVERVIEW_FOLLOWS_VAL, ARTnumber);
+ fflush(stdout);
+ if (PERMaccessconf->nnrpdoverstats)
+ gettimeofday(&stv, NULL);
+
+ /* If OVSTATICSEARCH is true, then the data returned by OVsearch is only
+ valid until the next call to OVsearch. In this case, we must use
+ SendIOb because it copies the data. */
+ OVctl(OVSTATICSEARCH, &useIOb);
+
+ while (OVsearch(handle, &artnum, &data, &len, &token, NULL)) {
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&etv, NULL);
+ OVERtime+=(etv.tv_sec - stv.tv_sec) * 1000;
+ OVERtime+=(etv.tv_usec - stv.tv_usec) / 1000;
+ }
+ if (len == 0 || (PERMaccessconf->nnrpdcheckart && !ARTinstorebytoken(token))) {
+ if (PERMaccessconf->nnrpdoverstats) {
+ OVERmiss++;
+ gettimeofday(&stv, NULL);
+ }
+ continue;
+ }
+ if (PERMaccessconf->nnrpdoverstats) {
+ OVERhit++;
+ OVERsize += len;
+ }
+ vector = overview_split(data, len, NULL, vector);
+ r = overview_getheader(vector, OVERVIEW_MESSAGE_ID, OVextra);
+ cache_add(HashMessageID(r), token);
+ free(r);
+ if (VirtualPathlen > 0 && overhdr_xref != -1) {
+ if ((overhdr_xref + 1) >= vector->count)
+ continue;
+ p = vector->strings[overhdr_xref] + sizeof("Xref: ") - 1;
+ while ((p < data + len) && *p == ' ')
+ ++p;
+ q = memchr(p, ' ', data + len - p);
+ if (q == NULL)
+ continue;
+ if(useIOb) {
+ SendIOb(data, p - data);
+ SendIOb(VirtualPath, VirtualPathlen - 1);
+ SendIOb(q, len - (q - data));
+ } else {
+ SendIOv(data, p - data);
+ SendIOv(VirtualPath, VirtualPathlen - 1);
+ SendIOv(q, len - (q - data));
+ }
+ } else {
+ if(useIOb)
+ SendIOb(data, len);
+ else
+ SendIOv(data, len);
+ }
+ if (PERMaccessconf->nnrpdoverstats)
+ gettimeofday(&stv, NULL);
+ }
+
+ if (vector)
+ cvector_free(vector);
+
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&etv, NULL);
+ OVERtime+=(etv.tv_sec - stv.tv_sec) * 1000;
+ OVERtime+=(etv.tv_usec - stv.tv_usec) / 1000;
+ }
+ if(useIOb) {
+ SendIOb(".\r\n", 3);
+ PushIOb();
+ } else {
+ SendIOv(".\r\n", 3);
+ PushIOv();
+ }
+ if (PERMaccessconf->nnrpdoverstats)
+ gettimeofday(&stv, NULL);
+ OVclosesearch(handle);
+ if (PERMaccessconf->nnrpdoverstats) {
+ gettimeofday(&etv, NULL);
+ OVERtime+=(etv.tv_sec - stv.tv_sec) * 1000;
+ OVERtime+=(etv.tv_usec - stv.tv_usec) / 1000;
+ }
+
+}
+
+/*
+** XHDR and XPAT extensions. Note that HDR as specified in the new NNTP
+** draft works differently than XHDR has historically, so don't just use this
+** function to implement it without reviewing the differences.
+*/
+/* ARGSUSED */
+void CMDpat(int ac, char *av[])
+{
+ char *p;
+ int i;
+ ARTRANGE range;
+ bool IsLines;
+ bool DidReply;
+ char *header;
+ char *pattern;
+ char *text;
+ int Overview;
+ ARTNUM artnum;
+ char buff[SPOOLNAMEBUFF];
+ void *handle;
+ char *data;
+ int len;
+ TOKEN token;
+ struct cvector *vector = NULL;
+
+ if (!PERMcanread) {
+ Printf("%s\r\n", NOACCESS);
+ return;
+ }
+
+ header = av[1];
+ IsLines = (strcasecmp(header, "lines") == 0);
+
+ if (ac > 3) /* XPAT */
+ pattern = Glom(&av[3]);
+ else
+ pattern = NULL;
+
+ do {
+ /* Message-ID specified? */
+ if (ac > 2 && av[2][0] == '<') {
+ p = av[2];
+ if (!ARTopenbyid(p, &artnum, false)) {
+ Printf("%d No such article.\r\n", NNTP_DONTHAVEIT_VAL);
+ break;
+ }
+ if (!PERMartok()) {
+ ARTclose();
+ Printf("%s\r\n", NOACCESS);
+ break;
+ }
+
+ Printf("%d %s matches follow (ID)\r\n", NNTP_HEAD_FOLLOWS_VAL,
+ header);
+ if ((text = GetHeader(header)) != NULL
+ && (!pattern || uwildmat_simple(text, pattern)))
+ Printf("%s %s\r\n", p, text);
+
+ ARTclose();
+ Printf(".\r\n");
+ break;
+ }
+
+ if (GRPcount == 0) {
+ Reply("%s\r\n", ARTnotingroup);
+ break;
+ }
+
+ /* Range specified. */
+ if (!CMDgetrange(ac - 1, av + 1, &range, &DidReply)) {
+ if (!DidReply) {
+ Reply("%d %s no matches follow (range)\r\n",
+ NNTP_HEAD_FOLLOWS_VAL, header ? header : "\"\"");
+ Printf(".\r\n");
+ break;
+ }
+ }
+
+ /* In overview? */
+ Overview = overview_index(header, OVextra);
+
+ /* Not in overview, we have to fish headers out from the articles */
+ if (Overview < 0 ) {
+ Reply("%d %s matches follow (art)\r\n", NNTP_HEAD_FOLLOWS_VAL,
+ header);
+ for (i = range.Low; i <= range.High && range.High > 0; i++) {
+ if (!ARTopen(i))
+ continue;
+ p = GetHeader(header);
+ if (p && (!pattern || uwildmat_simple(p, pattern))) {
+ snprintf(buff, sizeof(buff), "%u ", i);
+ SendIOb(buff, strlen(buff));
+ SendIOb(p, strlen(p));
+ SendIOb("\r\n", 2);
+ }
+ ARTclose();
+ }
+ SendIOb(".\r\n", 3);
+ PushIOb();
+ break;
+ }
+
+ /* Okay then, we can grab values from overview. */
+ handle = (void *)OVopensearch(GRPcur, range.Low, range.High);
+ if (handle == NULL) {
+ Reply("%d %s no matches follow (NOV)\r\n.\r\n",
+ NNTP_HEAD_FOLLOWS_VAL, header);
+ break;
+ }
+
+ Printf("%d %s matches follow (NOV)\r\n", NNTP_HEAD_FOLLOWS_VAL,
+ header);
+ while (OVsearch(handle, &artnum, &data, &len, &token, NULL)) {
+ if (len == 0 || (PERMaccessconf->nnrpdcheckart
+ && !ARTinstorebytoken(token)))
+ continue;
+ vector = overview_split(data, len, NULL, vector);
+ p = overview_getheader(vector, Overview, OVextra);
+ if (p != NULL) {
+ if (PERMaccessconf->virtualhost &&
+ Overview == overhdr_xref) {
+ p = vhost_xref(p);
+ if (p == NULL)
+ continue;
+ }
+ if (!pattern || uwildmat_simple(p, pattern)) {
+ snprintf(buff, sizeof(buff), "%lu ", artnum);
+ SendIOb(buff, strlen(buff));
+ SendIOb(p, strlen(p));
+ SendIOb("\r\n", 2);
+ }
+ free(p);
+ }
+ }
+ SendIOb(".\r\n", 3);
+ PushIOb();
+ OVclosesearch(handle);
+ } while (0);
+
+ if (vector)
+ cvector_free(vector);
+
+ if (pattern)
+ free(pattern);
+}
fi
-HOSTNAME=`hostname 2> /dev/null || uname -n`
+HOSTNAME=server.example.net
if test $ac_cv_prog_gcc = yes; then
Import the keys of the NoCeM issuers you trust in order to check
the authenticity of their notices. You can do:
- gpg --no-default-keyring --primary-keyring <pathetc>/pgp/ncmring.gpg --import <key-file>
+ gpg --no-default-keyring --primary-keyring <pathetc>/pgp/ncmring.gpg \
+ --no-options --allow-non-selfsigned-uid --no-permission-warning \
+ --batch --import <key-file>
where <pathetc> is the value of the I<pathetc> parameter set in F<inn.conf>
and <key-file> the file containing the key(s) to import. The keyring
.el .IP "\f(CWbuffindexed\fR" 4
.IX Item "buffindexed"
Stores overview data and index information into buffers, which are
-preconfigured files defined in \fIbuffinedexed.conf\fR. \f(CW\*(C`buffindexed\*(C'\fR never
+preconfigured files defined in \fIbuffindexed.conf\fR. \f(CW\*(C`buffindexed\*(C'\fR never
consumes additional disk space beyond that allocated to these buffers.
.ie n .IP """tradindexed""" 4
.el .IP "\f(CWtradindexed\fR" 4
Import the keys of the NoCeM issuers you trust in order to check
the authenticity of their notices. You can do:
.Sp
-.Vb 1
-\& gpg \-\-no\-default\-keyring \-\-primary\-keyring <pathetc>/pgp/ncmring.gpg \-\-import <key\-file>
+.Vb 3
+\& gpg \-\-no\-default\-keyring \-\-primary\-keyring=/etc/news/pgp/ncmring.gpg \e
+\& \-\-no\-options \-\-allow\-non\-selfsigned\-uid \-\-no\-permission\-warning \e
+\& \-\-batch \-\-import <key\-file>
.Ve
.Sp
where <pathetc> is the value of the \fIpathetc\fR parameter set in \fIinn.conf\fR
# endif
#endif
#ifndef PERL_VERSION
+# define PERL_REVISION (5)
# ifdef PERL_PATCHLEVEL
# define PERL_VERSION PERL_PATCHLEVEL
# else
# define ERRSV perl_get_sv("@",false)
#endif
-#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 4))
+#if (PERL_REVISION == 5) && ((PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 4)))
# define PL_sv_undef sv_undef
# define PL_sv_yes sv_yes
# define PL_sv_no sv_no
# define PL_copline copline
#endif
-#if (PERL_VERSION < 5)
+#if (PERL_REVISION == 5) && (PERL_VERSION < 5)
# undef dTHR
# ifdef WIN32
# define dTHR extern int Perl___notused
!DISTwantany(sp->Distributions, list))
/* Not in the site's desired list of distributions. */
continue;
- if (sp->DistRequired && list == NULL)
+ if (sp->DistRequired && (list == NULL || *list == NULL))
/* Site requires Distribution header and there isn't one. */
continue;
CV * filter;
int i, rc;
char * p;
- static SV * body = NULL;
static char buf[256];
if (!PerlFilterActive) return NULL;
}
/* Store the article body. We don't want to make another copy of it,
- since it could potentially be quite large. Instead, stash the
- pointer in the static SV * body. We set LEN to 0 and inc the
- refcount to tell Perl not to free it (either one should be enough).
- Requires 5.004. In testing, this produced a 17% speed improvement
- over making a copy of the article body for a fairly heavy filter. */
+ * since it could potentially be quite large. In testing, this produced
+ * a 17% speed improvement over making a copy of the article body
+ * for a fairly heavy filter.
+ * Available since Perl 5.7.1, newSVpvn_share allows to avoid such
+ * a copy (getting round its use for older versions of Perl leads
+ * to unreliable SV * bodies as for regexps). And for Perl not to
+ * compute a hash for artBody, we give it "42". */
if (artBody) {
- if (!body) {
- body = newSV(0);
- (void) SvUPGRADE(body, SVt_PV);
- }
- SvPVX(body) = artBody;
- SvCUR_set(body, artLen);
- SvLEN_set(body, 0);
- SvPOK_on(body);
- (void) SvREADONLY_on(body);
- (void) SvREFCNT_inc(body);
- hv_store(hdr, "__BODY__", 8, body, 0);
+#if (PERL_REVISION == 5) && ((PERL_VERSION < 7) || ((PERL_VERSION == 7) && (PERL_SUBVERSION < 1)))
+ hv_store(hdr, "__BODY__", 8, newSVpv(artBody, artLen), 0);
+#else
+ hv_store(hdr, "__BODY__", 8, newSVpvn_share(artBody, artLen, 42), 0);
+#endif /* Perl < 5.7.1 */
}
hv_store(hdr, "__LINES__", 9, newSViv(lines), 0);
status = xmalloc(sizeof(STATUS));
peers++; /* a new peer */
strlcpy(status->name, TempString, sizeof(status->name));
- strlcpy(status->ip_addr,
- sprint_sockaddr((struct sockaddr *)&cp->Address),
- sizeof(status->ip_addr));
+ if (cp->Address.ss_family == 0) {
+ /* Connections from lc.c do not have an IP address. */
+ memset(&status->ip_addr, 0, sizeof(status->ip_addr));
+ } else {
+ strlcpy(status->ip_addr,
+ sprint_sockaddr((struct sockaddr *)&cp->Address),
+ sizeof(status->ip_addr));
+ }
status->can_stream = cp->Streaming;
status->seconds = status->Size = status->DuplicateSize = 0;
status->Ihave = status->Ihave_Duplicate =
if (ac > 1)
ARTnumber = tart;
if ((msgid = GetHeader("Message-ID")) == NULL) {
+ ARTclose();
Reply("%s\r\n", ARTnoartingroup);
return;
}
if (!ARTopen(ARTnumber))
continue;
msgid = GetHeader("Message-ID");
+ ARTclose();
} while (msgid == NULL);
- ARTclose();
Reply("%d %d %s Article retrieved; request text separately.\r\n",
NNTP_NOTHING_FOLLOWS_VAL, ARTnumber, msgid);
}
/* Parse range. */
if (!CMDgetrange(ac, av, &range, &DidReply)) {
- if (!DidReply) {
- Reply("%d data follows\r\n", NNTP_OVERVIEW_FOLLOWS_VAL);
- Printf(".\r\n");
+ if (DidReply) {
return;
}
}
Printf("%d No such article.\r\n", NNTP_DONTHAVEIT_VAL);
break;
}
+ if (!PERMartok()) {
+ ARTclose();
+ Printf("%s\r\n", NOACCESS);
+ break;
+ }
+
Printf("%d %s matches follow (ID)\r\n", NNTP_HEAD_FOLLOWS_VAL,
header);
if ((text = GetHeader(header)) != NULL
/* Range specified. */
if (!CMDgetrange(ac - 1, av + 1, &range, &DidReply)) {
- if (!DidReply) {
- Reply("%d %s no matches follow (range)\r\n",
- NNTP_HEAD_FOLLOWS_VAL, header ? header : "\"\"");
- Printf(".\r\n");
+ if (DidReply) {
break;
}
}
SendIOb(buff, strlen(buff));
SendIOb(p, strlen(p));
SendIOb("\r\n", 2);
- ARTclose();
}
+ ARTclose();
}
SendIOb(".\r\n", 3);
PushIOb();
result=tls_start_servertls(0, /* read */
1); /* write */
if (result==-1) {
- Reply("%d Starttls failed\r\n", NNTP_STARTTLS_BAD_VAL);
+ /* No reply because we have already sent NNTP_STARTTLS_NEXT_VAL. */
return;
}
nnrpd_starttls_done = 1;
X509_verify_cert_error_string(err));
if (verify_depth >= depth) {
- ok = 0;
+ ok = 1;
verify_error = X509_V_OK;
} else {
ok = 0;
# index(0-65535) : path to buffer file :
# length of buffer in kilobytes in decimal (1KB = 1024 bytes)
-0:/var/news/spool/overview/OV1:1536000
-1:/var/news/spool/overview/OV2:1536000
+0:/var/spool/news/overview/OV1:1536000
+1:/var/spool/news/overview/OV2:1536000
data {
name "Spooled";
color "#AF00FF";
- value "%innfeed_spooled,";
+ value "%innfeed_spooled";
};
};
};
color "#FFAF00";
value "%innfeed_rejected_size";
};
- data {
- name "Total";
- color "#00FF00";
- value "%innfeed_accepted_size +
- %innfeed_rejected_size";
- };
};
};
name "Rej";
format_name "%4s";
format "%4d";
- value "$nnrpd_post_rej{$key} +
- $nnrpd_post_error{$key}";
+ value "($nnrpd_post_rej{$key}||0) +
+ ($nnrpd_post_error{$key}||0)";
total "total(%nnrpd_post_rej) +
total(%nnrpd_post_error)";
};
name "Rej";
format_name "%4s";
format "%4d";
- value "$nnrpd_dom_post_rej{$key} +
- $nnrpd_dom_post_error{$key}";
+ value "($nnrpd_dom_post_rej{$key}||0) +
+ ($nnrpd_dom_post_error{$key}||0)";
total "total(%nnrpd_dom_post_rej) +
total(%nnrpd_dom_post_error)";
};
$IMG_pth = $ref{'webpath'} if defined $ref{'webpath'};
$IMG_dir = $HTML_dir . "/" . $IMG_pth
- if (defined $output{'default'}{'html_dir'} ||
+ if (defined $output{'default'}{'img_dir'} ||
defined $ref{'w'} || defined $ref{'webpath'})
&&
(defined $output{'default'}{'html_dir'} ||
# The exact timers change from various versions of INN, so try to deal
# with this in a general fashion.
if ($left =~ m/^\S+\s+ # ME
- time\ (\d+)\s+ # time
- ((?:\S+\ \d+\(\d+\)\s*)+) # timer values
+ time\s(\d+)\s+ # time
+ ((?:\S+\s\d+\(\d+\)\s*)+) # timer values
$/ox) {
$innd_time_times += $1;
my $timers = $2;
# ME time X nnnn X(X) [...]
return 1 if $left =~ m/backlogstats/;
if ($left =~ m/^\S+\s+ # ME
- time\ (\d+)\s+ # time
- ((?:\S+\ \d+\(\d+\)\s*)+) # timer values
+ time\s(\d+)\s+ # time
+ ((?:\S+\s\d+\(\d+\)\s*)+) # timer values
$/ox) {
$innfeed_time_times += $1;
my $timers = $2;
# The exact timers change from various versions of INN, so try to deal
# with this in a general fashion.
if ($left =~ m/^\S+\s+ # ME
- time\ (\d+)\s+ # time
- ((?:\S+\ \d+\(\d+\)\s*)+) # timer values
+ time\s(\d+)\s+ # time
+ ((?:\S+\s\d+\(\d+\)\s*)+) # timer values
$/ox) {
$nnrpd_time_times += $1;
my $timers = $2;
$nocem_totalids{$nocem_lastid} += $2;
return 1;
}
- if ($left =~ /bad signature from (.*)/o) {
+ if ($left =~ /Article <[^>]*>: (.*) \(ID [[:xdigit:]]*\) not in keyring/o) {
+ $nocem_badsigs{$1}++;
+ $nocem_goodsigs{$1} = 0 unless ($nocem_goodsigs{$1});
+ $nocem_totalbad++;
+ $nocem_lastid = $1;
+ return 1;
+ }
+ if ($left =~ /Article <[^>]*>: bad signature from (.*)/o) {
$nocem_badsigs{$1}++;
$nocem_goodsigs{$1} = 0 unless ($nocem_goodsigs{$1});
$nocem_totalbad++;
$nocem_lastid = $1;
return 1;
}
+ if ($left =~ /Article <[^>]*>: malformed signature/o) {
+ $nocem_badsigs{'N/A'}++;
+ $nocem_goodsigs{'N/A'} = 0 unless ($nocem_goodsigs{'N/A'});
+ $nocem_totalbad++;
+ $nocem_lastid = 'N/A';
+ return 1;
+ }
+
return 1;
}
## Don't use parallel rules -- we want this to be viewed carefully.
install: all $(PAUSE) install-config $(RELOAD_AND_GO)
reload-install: all pause install-config reload go
-install-config: update $(REST_INSTALLED) $(SPECIAL)
+install-config: update $(REST_INSTALLED) #$(SPECIAL)
## Install scripts, not per-host config files.
update: all $(MOST_INSTALLED)