From 8f96ca50aa0f9edfd4cd9597dedeeaea07134f7f Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 25 Nov 2009 18:15:41 +0000 Subject: [PATCH] run debian/rules patch --- .pc/.version | 1 + .pc/applied-patches | 13 + .pc/configure-hostname/.timestamp | 0 .pc/configure-hostname/configure | 11907 ++++++++++++++++ .pc/debian-paths/.timestamp | 0 .pc/debian-paths/samples/buffindexed.conf | 11 + .pc/fix_ad_flag/.timestamp | 0 .pc/fix_ad_flag/innd/art.c | 2545 ++++ .pc/fix_body_regexps/.timestamp | 0 .pc/fix_body_regexps/include/ppport.h | 195 + .pc/fix_body_regexps/innd/perl.c | 502 + .pc/no-makedbz-on-install/.timestamp | 0 .pc/no-makedbz-on-install/site/Makefile | 268 + .pc/nocem-gpg-import/.timestamp | 0 .pc/nocem-gpg-import/control/perl-nocem.in | 629 + .pc/nocem-gpg-import/doc/man/perl-nocem.8 | 253 + .pc/typo_inn_conf_man/.timestamp | 0 .pc/typo_inn_conf_man/doc/man/inn.conf.5 | 1220 ++ .pc/u_innreport_misc/.timestamp | 0 .../samples/innreport.conf.in | 2479 ++++ .pc/u_innreport_misc/scripts/innreport.in | 2598 ++++ .pc/u_innreport_misc/scripts/innreport_inn.pm | 2212 +++ .pc/u_right_length/.timestamp | 0 .pc/u_right_length/nnrpd/tls.c | 713 + .pc/u_status_init_ip/.timestamp | 0 .pc/u_status_init_ip/innd/status.c | 359 + .pc/u_tls_duplicate_reply/.timestamp | 0 .pc/u_tls_duplicate_reply/nnrpd/misc.c | 552 + .pc/u_xhdr_permissions/.timestamp | 0 .pc/u_xhdr_permissions/nnrpd/article.c | 1105 ++ .pc/u_xover_duplicate_reply/.timestamp | 0 .pc/u_xover_duplicate_reply/nnrpd/article.c | 1112 ++ .stamp-patched | 0 configure | 2 +- control/perl-nocem.in | 4 +- doc/man/inn.conf.5 | 2 +- doc/man/perl-nocem.8 | 6 +- include/ppport.h | 5 +- innd/art.c | 2 +- innd/perl.c | 29 +- innd/status.c | 11 +- nnrpd/article.c | 20 +- nnrpd/misc.c | 2 +- nnrpd/tls.c | 2 +- samples/buffindexed.conf | 4 +- samples/innreport.conf.in | 16 +- scripts/innreport.in | 2 +- scripts/innreport_inn.pm | 29 +- site/Makefile | 2 +- 49 files changed, 28751 insertions(+), 61 deletions(-) create mode 100644 .pc/.version create mode 100644 .pc/applied-patches create mode 100644 .pc/configure-hostname/.timestamp create mode 100755 .pc/configure-hostname/configure create mode 100644 .pc/debian-paths/.timestamp create mode 100644 .pc/debian-paths/samples/buffindexed.conf create mode 100644 .pc/fix_ad_flag/.timestamp create mode 100644 .pc/fix_ad_flag/innd/art.c create mode 100644 .pc/fix_body_regexps/.timestamp create mode 100644 .pc/fix_body_regexps/include/ppport.h create mode 100644 .pc/fix_body_regexps/innd/perl.c create mode 100644 .pc/no-makedbz-on-install/.timestamp create mode 100644 .pc/no-makedbz-on-install/site/Makefile create mode 100644 .pc/nocem-gpg-import/.timestamp create mode 100644 .pc/nocem-gpg-import/control/perl-nocem.in create mode 100644 .pc/nocem-gpg-import/doc/man/perl-nocem.8 create mode 100644 .pc/typo_inn_conf_man/.timestamp create mode 100644 .pc/typo_inn_conf_man/doc/man/inn.conf.5 create mode 100644 .pc/u_innreport_misc/.timestamp create mode 100644 .pc/u_innreport_misc/samples/innreport.conf.in create mode 100644 .pc/u_innreport_misc/scripts/innreport.in create mode 100644 .pc/u_innreport_misc/scripts/innreport_inn.pm create mode 100644 .pc/u_right_length/.timestamp create mode 100644 .pc/u_right_length/nnrpd/tls.c create mode 100644 .pc/u_status_init_ip/.timestamp create mode 100644 .pc/u_status_init_ip/innd/status.c create mode 100644 .pc/u_tls_duplicate_reply/.timestamp create mode 100644 .pc/u_tls_duplicate_reply/nnrpd/misc.c create mode 100644 .pc/u_xhdr_permissions/.timestamp create mode 100644 .pc/u_xhdr_permissions/nnrpd/article.c create mode 100644 .pc/u_xover_duplicate_reply/.timestamp create mode 100644 .pc/u_xover_duplicate_reply/nnrpd/article.c create mode 100644 .stamp-patched diff --git a/.pc/.version b/.pc/.version new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/.pc/.version @@ -0,0 +1 @@ +2 diff --git a/.pc/applied-patches b/.pc/applied-patches new file mode 100644 index 0000000..54c2954 --- /dev/null +++ b/.pc/applied-patches @@ -0,0 +1,13 @@ +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 diff --git a/.pc/configure-hostname/.timestamp b/.pc/configure-hostname/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/configure-hostname/configure b/.pc/configure-hostname/configure new file mode 100755 index 0000000..c4cf14e --- /dev/null +++ b/.pc/configure-hostname/configure @@ -0,0 +1,11907 @@ +#! /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 , 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 </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 <&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 < +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 < +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 < +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 <&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 <&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 <&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 &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 <&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 < 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 <> 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 +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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 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 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 <&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 + # , 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 <&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.so + # instead of lib.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 < +/* 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 <&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 < +/* 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 <&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 <&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 <&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 < +#endif + +#include + +#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 < +#endif + +#include + +#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 , 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 +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #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 +# 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 /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* 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> "${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 <> confdefs.h <> confdefs.h <&2; exit 1; } + fi + fi +fi + + + + + +cat >> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> 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 <> 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 <&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 < +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 < +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 <&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 <&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 <&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 < +/* 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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 +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 <&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 +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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 <&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 +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 <&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 < +/* 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 <&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 < +#include +#include +#include +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 +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 +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 < +#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 +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 <&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 < +/* 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 <&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 < +#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 <&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 <&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 <&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 < +#include +#include +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 < +#include +#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 +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 <&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 +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 <&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 < +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 < +#include +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +# if !HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#else +# if HAVE_STRINGS_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif +#include +#include +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 < +#include +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +# if !HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#else +# if HAVE_STRINGS_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif +#include +#include +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 < +#include +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +# if !HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#else +# if HAVE_STRINGS_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#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 < +#include +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +# if !HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#else +# if HAVE_STRINGS_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#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 < +#include +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 < +#include +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 <&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 <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 < +#include +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 < +#include +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 < +#if STDC_HEADERS +#include +#include +#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 +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 < +#if STDC_HEADERS +#include +#include +#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 < +#if STDC_HEADERS +#include +#include +#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 < +#if STDC_HEADERS +#include +#include +#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 < +#if STDC_HEADERS +#include +#include +#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 < +#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 < +#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 <&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 < +#ifdef STDC_HEADERS +# include +# include +#endif +#include +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 <&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 < +#ifdef STDC_HEADERS +# include +# include +#endif +#include +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 <&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 < +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_LIMITS_H +# include +#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 <&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 < +#include +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 < +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 < +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 < +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 < +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 < +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 < +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 < +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 < +#ifdef STDC_HEADERS +# include +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_SYS_BITYPES_H +# include +#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 <&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 < +#ifdef STDC_HEADERS +# include +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_SYS_BITYPES_H +# include +#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 <&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 <&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 < +#include +#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 <&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 < +#include +#include +#include +#if STDC_HEADERS || HAVE_STRING_H +# include +#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 < + #include + #include +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 < + #include + #include +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 < + #include + #include +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 < + #include + #include +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 < +#include +#include +#include + +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 < +#include + +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 < +/* 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 <&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 < +/* 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 <&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 < +/* 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 <&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 +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 <&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 < +/* 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 <&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 < +#include + +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 < +#include +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +# if !HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#else +# if HAVE_STRINGS_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif +#include +#include + +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 < +/* 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 <&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 < +#include +#include +#include +#if HAVE_UNISTD_H +# include +#endif +#include + +/* 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 < +#include +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +# if !HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#else +# if HAVE_STRINGS_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif +#include +#include +#include + +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 < +#include +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 < +#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 < +#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 <> confdefs.h < 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 </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 < 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 <> $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 <> $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 <> $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 <> $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 < /dev/null ; then + : +else + cat < + +#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 */ + + + +/* +** 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 . */ + 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; +} diff --git a/.pc/fix_body_regexps/.timestamp b/.pc/fix_body_regexps/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/fix_body_regexps/include/ppport.h b/.pc/fix_body_regexps/include/ppport.h new file mode 100644 index 0000000..d7d1fb6 --- /dev/null +++ b/.pc/fix_body_regexps/include/ppport.h @@ -0,0 +1,195 @@ + +#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 + , 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 () { + $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 () { $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 () { 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 +# 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 */ diff --git a/.pc/fix_body_regexps/innd/perl.c b/.pc/fix_body_regexps/innd/perl.c new file mode 100644 index 0000000..a994242 --- /dev/null +++ b/.pc/fix_body_regexps/innd/perl.c @@ -0,0 +1,502 @@ +/* $Id: perl.c 7815 2008-05-05 08:43:58Z iulius $ +** +** Perl filtering support for innd. +** +** Originally written by Christophe Wolfhugel (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 +#include +#include +#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 . +*/ +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) */ diff --git a/.pc/no-makedbz-on-install/.timestamp b/.pc/no-makedbz-on-install/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/no-makedbz-on-install/site/Makefile b/.pc/no-makedbz-on-install/site/Makefile new file mode 100644 index 0000000..4df27f7 --- /dev/null +++ b/.pc/no-makedbz-on-install/site/Makefile @@ -0,0 +1,268 @@ +## $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) $? $@ diff --git a/.pc/nocem-gpg-import/.timestamp b/.pc/nocem-gpg-import/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/nocem-gpg-import/control/perl-nocem.in b/.pc/nocem-gpg-import/control/perl-nocem.in new file mode 100644 index 0000000..5630d12 --- /dev/null +++ b/.pc/nocem-gpg-import/control/perl-nocem.in @@ -0,0 +1,629 @@ +#!/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 +# Copyright 2001 by Marco d'Itri +# 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 () { + 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('', ); + 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 = ) !~ /^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 = ) !~ /^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 = ) !~ /^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 () { + 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 + +=head1 SYNOPSIS + +perl-nocem + +=head1 DESCRIPTION + +NoCeM, which is pronounced I, 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. It is +intended to eventually replace the protocol for third-party cancel +messages. + +B 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 /pgp/ncmring.gpg --import + +where is the value of the I parameter set in F +and the file containing the key(s) to import. The keyring +must be located in I/pgp/ncmring.gpg (create the directory +before using B). 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: +L. You can even +download there a unique file which contains all the keys. + +=item 2. + +Create a F config file in I 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. + +=item 3. + +Add to the F file an entry like this one in order to feed +B the NoCeM notices posted to alt.nocem.misc and +news.lists.filters: + + nocem!\ + :!*,alt.nocem.misc,news.lists.filters\ + :Tc,Wf,Ap:/perl-nocem + +with the correct path to B, located in . Then, reload +the F file (C). + +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 with a NoCeM notice, using: + + grephistory '' | perl-nocem + +Indeed, B expects tokens on its standard input, and +B 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 in the Path: header (see the +I parameter in F). + +=head1 FILES + +=over 4 + +=item I/perl-nocem + +The Perl script itself used to process NoCeM notices. + +=item I/nocem.ctl + +The configuration file which specifies the NoCeM notices to be processed. + +=item I/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 . + +Copyright 2001 by Marco d'Itri . + +$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 diff --git a/.pc/nocem-gpg-import/doc/man/perl-nocem.8 b/.pc/nocem-gpg-import/doc/man/perl-nocem.8 new file mode 100644 index 0000000..cdf7d65 --- /dev/null +++ b/.pc/nocem-gpg-import/doc/man/perl-nocem.8 @@ -0,0 +1,253 @@ +.\" 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 /pgp/ncmring.gpg \-\-import +.Ve +.Sp +where is the value of the \fIpathetc\fR parameter set in \fIinn.conf\fR +and 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: +. 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:/perl\-nocem +.Ve +.Sp +with the correct path to \fBperl-nocem\fR, located in . 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 '' | 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 . +.PP +Copyright 2001 by Marco d'Itri . +.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). diff --git a/.pc/typo_inn_conf_man/.timestamp b/.pc/typo_inn_conf_man/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/typo_inn_conf_man/doc/man/inn.conf.5 b/.pc/typo_inn_conf_man/doc/man/inn.conf.5 new file mode 100644 index 0000000..f525e06 --- /dev/null +++ b/.pc/typo_inn_conf_man/doc/man/inn.conf.5 @@ -0,0 +1,1220 @@ +.\" 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 +\& : +.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. 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 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`\*(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 @\fIfromhost\fR, where +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 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. diff --git a/.pc/u_innreport_misc/.timestamp b/.pc/u_innreport_misc/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/u_innreport_misc/samples/innreport.conf.in b/.pc/u_innreport_misc/samples/innreport.conf.in new file mode 100644 index 0000000..b6899fa --- /dev/null +++ b/.pc/u_innreport_misc/samples/innreport.conf.in @@ -0,0 +1,2479 @@ +########################################################## +# 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 +# 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 news.y.z"; + # footer "Local contact: x@y.z"; + # 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)"; + }; +}; diff --git a/.pc/u_innreport_misc/scripts/innreport.in b/.pc/u_innreport_misc/scripts/innreport.in new file mode 100644 index 0000000..334f748 --- /dev/null +++ b/.pc/u_innreport_misc/scripts/innreport.in @@ -0,0 +1,2598 @@ +#! /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: +# +# 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 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 = ; + 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 = ; + 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 () { + 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 < + +$Title: index + +$HTML_header +
+
+$title - archives +
+
+

+

+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 .= "\"Graph\"\n"; + $i++; + } + $result .= "

\n"; + } + $i = 0; + $result .= ""; + 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 "", $#list + 1; + } + else { + $result .= ""; + } + foreach (@list) { + $temp .= ""; + } + $i++; + } + $result .= "\n$temp\n"; + + $i = 0; + foreach (sort {$b cmp $a} (keys %data)) { + if ($CYCLE == 0 || $i < $CYCLE) { + my @list = split /\|/, $data{$_}; + my $str = ""; + while (@list) { + $str .= ""; + } + $str .= "\n"; + $result .= "$str"; + } + $i++; + } + $result .= "
$title$title$_
"; + $str .= "" if -e "$rep/$_"; + $str .= shift @list; + $str .= "" if -e "$rep/$_";; + $str .= ""; + my $t = shift @list; + $t =~ s/^\0+//o; # remove garbage, if any. + $str .= "$t
\n

\n


"; + $result .= "innreport $version (c) 1996-1999 "; + $result .= "by Fabien Tassin <"; + $result .= "fta\@sofaraway.org>.\n"; + if (defined ($output{'default'}{'footer'})) { + my ($t) = $output{'default'}{'footer'} =~ m/^\"\s*(.*?)\s*\"$/o; + $t =~ s/\\\"/\"/go; + $result .= "
" . $t; + } + $result .= "$HTML_footer\n\n\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; + 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 "\n" . + "\n\n$Title: $first_date\n" . + "\n\n\n" . + "$HTML_header\n

$title

\n" . + "

$first_date -- $last_date

\n
\n


\n"; + + # Index + print HTML "

    \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 "
  • $string\n" if %data && $want; + } + print HTML "


\n"; + } + if (@unrecognize && $WANT_UNKNOWN) { + my $mm = $#unrecognize; + print HTML "" if $HTML && $WANT_HTML_UNKNOWN; + print "Unknown entries from news log file:\n"; + print HTML "Unknown entries from news log file:

\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%%)
\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; + print HTML "$unrecognize[$l]
\n"; + } + } + print "\n"; + print HTML "


\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 <fta\@sofaraway.org>. +EOT + if (defined $$h{'default'}{'footer'}) { + my ($t) = $$h{'default'}{'footer'} =~ m/^\"\s*(.*?)\s*\"$/o; + $t =~ s/\\\"/\"/go; + print HTML "
" . $t; + } + print HTML "\n$HTML_footer"; + printf HTML "\n", second2time(time - $start_time); + print HTML "\n\n\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 ""; + my $html = $t; + $html =~ s/(:?)$/ [Top $TOP_HTML]$1/o if $TOP_HTML > 0; + $html =~ s|^(.*)$|$1|; + print HTML "$html\n

\n

\n\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 "", $v2; + } + $first++; + } + $s =~ s/\s*$//; + print "$s\n" if $TEXT; + $s = ''; + if ($HTML) { + print HTML "$html\n\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 .= ""; + } + else { + $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g; + $html .= $numbering ? "" : ''; + # unless $first; + $html .= sprintf "\n", $r; + $html .= ""; + } + } + } + else { + if ($wtext) { + $s .= " " if $first == 1; + $s .= sprintf $v1 . " ", $r; + } + if ($HTML && $whtml) { + $html .= $numbering ? "" : '' if $first == 1; + $v1 =~ s/\%-?(?:\d+(?:\.\d+)?)?s/\%s/g; + my $temp = $first > 1 ? "RIGHT" : "LEFT"; + $html .= sprintf "", $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 "$html\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 .= "" if $HTML; + $html .= "" 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|(.*)|$1|o unless $first > 1; + $html .= sprintf "", $r; + } + $first++; + } + $s =~ s/\s*$//; + $s =~ s/\\n//g; + print "$s\n" if $TEXT; + print HTML "$html\n" if $HTML; + } + } + print "\n" if $TEXT; + print HTML "\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|(.*)|$1|o unless $first; + $html .= $first == 1 ? "" : + sprintf "", $r; + } + $first++; + } + $s =~ s/\s*$//; + $s =~ s/\\n//g; + print "$s\n" if $TEXT; + print HTML "$html\n
$v1
$num_d$v1
$v1
$v1
$v1
\n
\n

\n


\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 .= "$num" if $numbering && !$first; + my $temp = $first ? "RIGHT" : "LEFT"; + $html .= sprintf "$v1", $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 "$html\n"; + $html = ''; + } + } + print "\n" if $TEXT; + print HTML "\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|(.*)|$1|o unless $first; + $html .= sprintf "$v1", $r; + } + $first++; + } + $s =~ s/\s*$//; + print "$s\n" if $TEXT; + if ($HTML) { + print HTML "$html\n"; + print HTML "\n

\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 "

\"$title\"> $HTML_output") || + die "Error: cant open $HTML_output\n"; + print HTML "WIDTH=\"$xmax\" HEIGHT=\"$y\" "; + print HTML "SRC=\"$IMG_pth$report$s.$GD_FORMAT\">
\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 "
\"$title\"
\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 "

\n"; + } + print HTML "\n


\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 = )) { + $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 .= ; # 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 \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 ########################## diff --git a/.pc/u_innreport_misc/scripts/innreport_inn.pm b/.pc/u_innreport_misc/scripts/innreport_inn.pm new file mode 100644 index 0000000..d2943fe --- /dev/null +++ b/.pc/u_innreport_misc/scripts/innreport_inn.pm @@ -0,0 +1,2212 @@ +########################################################## +# 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 +# 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 size [feeds] + # or + # server (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 + 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 path.. + if ($left =~ /^duplicate /o) { + $rnews_duplicate++; + return 1; + } + # offered 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 " good signature from foo@bar.com + if ($left =~ /good signature from (.*)/o) { + $nocem_goodsigs{$1}++; + $nocem_totalgood++; + $nocem_lastid = $1; + return 1; + } + #
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; + } + #
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 + 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 () { + 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; diff --git a/.pc/u_right_length/.timestamp b/.pc/u_right_length/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/u_right_length/nnrpd/tls.c b/.pc/u_right_length/nnrpd/tls.c new file mode 100644 index 0000000..f31421a --- /dev/null +++ b/.pc/u_right_length/nnrpd/tls.c @@ -0,0 +1,713 @@ +/* tls.c --- TLSv1 functions + Copyright (C) 2000 Kenichi Okada + + Author: Kenichi Okada + Created: 2000-02-22 + + Keywords: TLS, OpenSSL + + Commentary: + + [RFC 2246] "The TLS Protocol Version 1.0" + by Christopher Allen and + Tim Dierks (1999/01) + + [RFC 2595] "Using TLS with IMAP, POP3 and ACAP" + by Chris Newman (1999/06) + +*/ + +#include +#include "config.h" +#include "nnrpd.h" + +#ifdef HAVE_SSL + +/* System library. */ + +#include +#include +#include +#include +#include +#include + +#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 - \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 */ diff --git a/.pc/u_status_init_ip/.timestamp b/.pc/u_status_init_ip/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/u_status_init_ip/innd/status.c b/.pc/u_status_init_ip/innd/status.c new file mode 100644 index 0000000..f3c2d8d --- /dev/null +++ b/.pc/u_status_init_ip/innd/status.c @@ -0,0 +1,359 @@ +/* $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,"\n\n\n", + innconf->status < MIN_REFRESH ? MIN_REFRESH : innconf->status); + fprintf (F, "%s: incoming feeds\n", innconf->pathhost); + fprintf (F, "\n\n
\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,"
\n\n\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; + } +} diff --git a/.pc/u_tls_duplicate_reply/.timestamp b/.pc/u_tls_duplicate_reply/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/u_tls_duplicate_reply/nnrpd/misc.c b/.pc/u_tls_duplicate_reply/nnrpd/misc.c new file mode 100644 index 0000000..fc91471 --- /dev/null +++ b/.pc/u_tls_duplicate_reply/nnrpd/misc.c @@ -0,0 +1,552 @@ +/* $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 +#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: + * backoff_postfast: + * backoff_postslow: + * backoff_trigger: + * backoff_db: + * backoff_auth: + * + * You may also specify posting backoffs on a per user basis. To do this + * turn on "backoff_auth" + * + * Now these are runtime constants. + */ +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 */ diff --git a/.pc/u_xhdr_permissions/.timestamp b/.pc/u_xhdr_permissions/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/u_xhdr_permissions/nnrpd/article.c b/.pc/u_xhdr_permissions/nnrpd/article.c new file mode 100644 index 0000000..e0f5b05 --- /dev/null +++ b/.pc/u_xhdr_permissions/nnrpd/article.c @@ -0,0 +1,1105 @@ +/* $Id: article.c 7538 2006-08-26 05:44:06Z eagle $ +** +** Article-related routines. +*/ + +#include "config.h" +#include "clibrary.h" +#include +#if HAVE_LIMITS_H +# include +#endif +#include + +#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); +} diff --git a/.pc/u_xover_duplicate_reply/.timestamp b/.pc/u_xover_duplicate_reply/.timestamp new file mode 100644 index 0000000..e69de29 diff --git a/.pc/u_xover_duplicate_reply/nnrpd/article.c b/.pc/u_xover_duplicate_reply/nnrpd/article.c new file mode 100644 index 0000000..92d8f76 --- /dev/null +++ b/.pc/u_xover_duplicate_reply/nnrpd/article.c @@ -0,0 +1,1112 @@ +/* $Id: article.c 7538 2006-08-26 05:44:06Z eagle $ +** +** Article-related routines. +*/ + +#include "config.h" +#include "clibrary.h" +#include +#if HAVE_LIMITS_H +# include +#endif +#include + +#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); +} diff --git a/.stamp-patched b/.stamp-patched new file mode 100644 index 0000000..e69de29 diff --git a/configure b/configure index c4cf14e..ae374be 100755 --- a/configure +++ b/configure @@ -5839,7 +5839,7 @@ else fi -HOSTNAME=`hostname 2> /dev/null || uname -n` +HOSTNAME=server.example.net if test $ac_cv_prog_gcc = yes; then diff --git a/control/perl-nocem.in b/control/perl-nocem.in index 5630d12..968d80a 100644 --- a/control/perl-nocem.in +++ b/control/perl-nocem.in @@ -521,7 +521,9 @@ Processing NoCeM notices is easy to set up: 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 /pgp/ncmring.gpg --import + gpg --no-default-keyring --primary-keyring /pgp/ncmring.gpg \ + --no-options --allow-non-selfsigned-uid --no-permission-warning \ + --batch --import where is the value of the I parameter set in F and the file containing the key(s) to import. The keyring diff --git a/doc/man/inn.conf.5 b/doc/man/inn.conf.5 index f525e06..77cf8c3 100644 --- a/doc/man/inn.conf.5 +++ b/doc/man/inn.conf.5 @@ -480,7 +480,7 @@ this parameter must be set if \fIenableoverview\fR is true (the default). .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 diff --git a/doc/man/perl-nocem.8 b/doc/man/perl-nocem.8 index cdf7d65..12f9b67 100644 --- a/doc/man/perl-nocem.8 +++ b/doc/man/perl-nocem.8 @@ -157,8 +157,10 @@ Processing NoCeM notices is easy to set up: 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 /pgp/ncmring.gpg \-\-import +.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 .Ve .Sp where is the value of the \fIpathetc\fR parameter set in \fIinn.conf\fR diff --git a/include/ppport.h b/include/ppport.h index d7d1fb6..2387f00 100644 --- a/include/ppport.h +++ b/include/ppport.h @@ -150,6 +150,7 @@ __DATA__ # endif #endif #ifndef PERL_VERSION +# define PERL_REVISION (5) # ifdef PERL_PATCHLEVEL # define PERL_VERSION PERL_PATCHLEVEL # else @@ -162,7 +163,7 @@ __DATA__ # 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 @@ -174,7 +175,7 @@ __DATA__ # 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 diff --git a/innd/art.c b/innd/art.c index 66f212b..bef61f7 100644 --- a/innd/art.c +++ b/innd/art.c @@ -1725,7 +1725,7 @@ ARTpropagate(ARTDATA *data, const char **hops, int hopcount, char **list, !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; diff --git a/innd/perl.c b/innd/perl.c index a994242..c0e286e 100644 --- a/innd/perl.c +++ b/innd/perl.c @@ -69,7 +69,6 @@ PLartfilter(const ARTDATA *data, char *artBody, long artLen, int lines) CV * filter; int i, rc; char * p; - static SV * body = NULL; static char buf[256]; if (!PerlFilterActive) return NULL; @@ -87,23 +86,19 @@ PLartfilter(const ARTDATA *data, char *artBody, long artLen, int lines) } /* 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); diff --git a/innd/status.c b/innd/status.c index f3c2d8d..e2040c1 100644 --- a/innd/status.c +++ b/innd/status.c @@ -153,9 +153,14 @@ STATUSsummary(void) 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 = diff --git a/nnrpd/article.c b/nnrpd/article.c index e0f5b05..5b9160e 100644 --- a/nnrpd/article.c +++ b/nnrpd/article.c @@ -688,6 +688,7 @@ void CMDfetch(int ac, char *av[]) if (ac > 1) ARTnumber = tart; if ((msgid = GetHeader("Message-ID")) == NULL) { + ARTclose(); Reply("%s\r\n", ARTnoartingroup); return; } @@ -745,9 +746,9 @@ void CMDnextlast(int ac UNUSED, char *av[]) 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); } @@ -854,9 +855,7 @@ void CMDxover(int ac, char *av[]) /* 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; } } @@ -1010,6 +1009,12 @@ void CMDpat(int ac, char *av[]) 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 @@ -1028,10 +1033,7 @@ void CMDpat(int ac, char *av[]) /* 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; } } @@ -1052,8 +1054,8 @@ void CMDpat(int ac, char *av[]) SendIOb(buff, strlen(buff)); SendIOb(p, strlen(p)); SendIOb("\r\n", 2); - ARTclose(); } + ARTclose(); } SendIOb(".\r\n", 3); PushIOb(); diff --git a/nnrpd/misc.c b/nnrpd/misc.c index fc91471..e4e0d4a 100644 --- a/nnrpd/misc.c +++ b/nnrpd/misc.c @@ -544,7 +544,7 @@ CMDstarttls(ac, av) 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; diff --git a/nnrpd/tls.c b/nnrpd/tls.c index f31421a..cfc8f03 100644 --- a/nnrpd/tls.c +++ b/nnrpd/tls.c @@ -257,7 +257,7 @@ static int verify_callback(int ok, X509_STORE_CTX * ctx) X509_verify_cert_error_string(err)); if (verify_depth >= depth) { - ok = 0; + ok = 1; verify_error = X509_V_OK; } else { ok = 0; diff --git a/samples/buffindexed.conf b/samples/buffindexed.conf index f61dac0..7ba411b 100644 --- a/samples/buffindexed.conf +++ b/samples/buffindexed.conf @@ -7,5 +7,5 @@ # 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 diff --git a/samples/innreport.conf.in b/samples/innreport.conf.in index b6899fa..215f63d 100644 --- a/samples/innreport.conf.in +++ b/samples/innreport.conf.in @@ -1267,7 +1267,7 @@ section innfeed_connect { data { name "Spooled"; color "#AF00FF"; - value "%innfeed_spooled,"; + value "%innfeed_spooled"; }; }; }; @@ -1347,12 +1347,6 @@ section innfeed_volume { color "#FFAF00"; value "%innfeed_rejected_size"; }; - data { - name "Total"; - color "#00FF00"; - value "%innfeed_accepted_size + - %innfeed_rejected_size"; - }; }; }; @@ -2116,8 +2110,8 @@ section nnrpd_groups { 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)"; }; @@ -2179,8 +2173,8 @@ section nnrpd_dom_groups { 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)"; }; diff --git a/scripts/innreport.in b/scripts/innreport.in index 334f748..241d10e 100644 --- a/scripts/innreport.in +++ b/scripts/innreport.in @@ -212,7 +212,7 @@ $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'} || + if (defined $output{'default'}{'img_dir'} || defined $ref{'w'} || defined $ref{'webpath'}) && (defined $output{'default'}{'html_dir'} || diff --git a/scripts/innreport_inn.pm b/scripts/innreport_inn.pm index d2943fe..4043f3e 100644 --- a/scripts/innreport_inn.pm +++ b/scripts/innreport_inn.pm @@ -440,8 +440,8 @@ sub collect { # 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; @@ -719,8 +719,8 @@ sub collect { # 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; @@ -1459,8 +1459,8 @@ sub collect { # 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; @@ -1683,13 +1683,28 @@ sub collect { $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; } diff --git a/site/Makefile b/site/Makefile index 4df27f7..e81d9eb 100644 --- a/site/Makefile +++ b/site/Makefile @@ -121,7 +121,7 @@ config: $(ALL) ## 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) -- 2.30.2